chef_data_bag_item resource.
This commit is contained in:
parent
d583b936b2
commit
406aba4a62
|
@ -1,6 +1,7 @@
|
||||||
package chef
|
package chef
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
@ -44,7 +45,7 @@ func Provider() terraform.ResourceProvider {
|
||||||
//"chef_client": resourceChefClient(),
|
//"chef_client": resourceChefClient(),
|
||||||
//"chef_cookbook": resourceChefCookbook(),
|
//"chef_cookbook": resourceChefCookbook(),
|
||||||
"chef_data_bag": resourceChefDataBag(),
|
"chef_data_bag": resourceChefDataBag(),
|
||||||
//"chef_data_bag_item": resourceChefDataBagItem(),
|
"chef_data_bag_item": resourceChefDataBagItem(),
|
||||||
//"chef_environment": resourceChefEnvironment(),
|
//"chef_environment": resourceChefEnvironment(),
|
||||||
//"chef_node": resourceChefNode(),
|
//"chef_node": resourceChefNode(),
|
||||||
//"chef_role": resourceChefRole(),
|
//"chef_role": resourceChefRole(),
|
||||||
|
@ -77,3 +78,20 @@ func providerPrivateKeyEnvDefault() (interface{}, error) {
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func jsonStateFunc(value interface{}) string {
|
||||||
|
// Parse and re-stringify the JSON to make sure it's always kept
|
||||||
|
// in a normalized form.
|
||||||
|
in, ok := value.(string)
|
||||||
|
if !ok {
|
||||||
|
return "null"
|
||||||
|
}
|
||||||
|
var tmp map[string]interface{}
|
||||||
|
|
||||||
|
// Assuming the value must be valid JSON since it passed okay through
|
||||||
|
// our prepareDataBagItemContent function earlier.
|
||||||
|
json.Unmarshal([]byte(in), &tmp)
|
||||||
|
|
||||||
|
jsonValue, _ := json.Marshal(&tmp)
|
||||||
|
return string(jsonValue)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
package chef
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
|
||||||
|
chefc "github.com/go-chef/chef"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceChefDataBagItem() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: CreateDataBagItem,
|
||||||
|
Read: ReadDataBagItem,
|
||||||
|
Delete: DeleteDataBagItem,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"data_bag_name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"content_json": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
StateFunc: jsonStateFunc,
|
||||||
|
},
|
||||||
|
"id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateDataBagItem(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*chefc.Client)
|
||||||
|
|
||||||
|
dataBagName := d.Get("data_bag_name").(string)
|
||||||
|
itemId, itemContent, err := prepareDataBagItemContent(d.Get("content_json").(string))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.DataBags.CreateItem(dataBagName, itemContent)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(itemId)
|
||||||
|
d.Set("id", itemId)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadDataBagItem(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*chefc.Client)
|
||||||
|
|
||||||
|
// The Chef API provides no API to read a data bag's metadata,
|
||||||
|
// but we can try to read its items and use that as a proxy for
|
||||||
|
// whether it still exists.
|
||||||
|
|
||||||
|
itemId := d.Id()
|
||||||
|
dataBagName := d.Get("data_bag_name").(string)
|
||||||
|
|
||||||
|
value, err := client.DataBags.GetItem(dataBagName, itemId)
|
||||||
|
if err != nil {
|
||||||
|
if errRes, ok := err.(*chefc.ErrorResponse); ok {
|
||||||
|
if errRes.Response.StatusCode == 404 {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonContent, err := json.Marshal(value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("content_json", string(jsonContent))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteDataBagItem(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
client := meta.(*chefc.Client)
|
||||||
|
|
||||||
|
itemId := d.Id()
|
||||||
|
dataBagName := d.Get("data_bag_name").(string)
|
||||||
|
|
||||||
|
err := client.DataBags.DeleteItem(dataBagName, itemId)
|
||||||
|
if err == nil {
|
||||||
|
d.SetId("")
|
||||||
|
d.Set("id", "")
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareDataBagItemContent(contentJson string) (string, interface{}, error) {
|
||||||
|
var value map[string]interface{}
|
||||||
|
err := json.Unmarshal([]byte(contentJson), &value)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var itemId string
|
||||||
|
if itemIdI, ok := value["id"]; ok {
|
||||||
|
itemId, _ = itemIdI.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
if itemId == "" {
|
||||||
|
return "", nil, fmt.Errorf("content_json must have id attribute, set to a string")
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemId, value, nil
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
package chef
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
chefc "github.com/go-chef/chef"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccDataBagItem_basic(t *testing.T) {
|
||||||
|
var dataBagItemName string
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccDataBagItemCheckDestroy(dataBagItemName),
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccDataBagItemConfig_basic,
|
||||||
|
Check: testAccDataBagItemCheck(
|
||||||
|
"chef_data_bag_item.test", &dataBagItemName,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccDataBagItemCheck(rn string, name *string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[rn]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("resource not found: %s", rn)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("data bag item id not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := testAccProvider.Meta().(*chefc.Client)
|
||||||
|
content, err := client.DataBags.GetItem("terraform-acc-test-bag-item-basic", rs.Primary.ID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error getting data bag item: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedContent := map[string]interface{}{
|
||||||
|
"id": "terraform_acc_test",
|
||||||
|
"something_else": true,
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(content, expectedContent) {
|
||||||
|
return fmt.Errorf("wrong content: expected %#v, got %#v", expectedContent, content)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected := "terraform_acc_test"; rs.Primary.Attributes["id"] != expected {
|
||||||
|
return fmt.Errorf("wrong id; expected %#v, got %#v", expected, rs.Primary.Attributes["id"])
|
||||||
|
}
|
||||||
|
|
||||||
|
*name = rs.Primary.ID
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccDataBagItemCheckDestroy(name string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
client := testAccProvider.Meta().(*chefc.Client)
|
||||||
|
_, err := client.DataBags.GetItem("terraform-acc-test-bag-item-basic", name)
|
||||||
|
if err == nil {
|
||||||
|
return fmt.Errorf("data bag item still exists")
|
||||||
|
}
|
||||||
|
if _, ok := err.(*chefc.ErrorResponse); err != nil && !ok {
|
||||||
|
return fmt.Errorf("got something other than an HTTP error (%v) when getting data bag item", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccDataBagItemConfig_basic = `
|
||||||
|
resource "chef_data_bag" "test" {
|
||||||
|
name = "terraform-acc-test-bag-item-basic"
|
||||||
|
}
|
||||||
|
resource "chef_data_bag_item" "test" {
|
||||||
|
data_bag_name = "terraform-acc-test-bag-item-basic"
|
||||||
|
depends_on = ["chef_data_bag.test"]
|
||||||
|
content_json = <<EOT
|
||||||
|
{
|
||||||
|
"id": "terraform_acc_test",
|
||||||
|
"something_else": true
|
||||||
|
}
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
`
|
Loading…
Reference in New Issue