121 lines
2.5 KiB
Go
121 lines
2.5 KiB
Go
|
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
|
||
|
}
|