github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/chef/provider.go (about) 1 package chef 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "strings" 9 "time" 10 11 "github.com/hashicorp/terraform/helper/schema" 12 "github.com/hashicorp/terraform/terraform" 13 14 chefc "github.com/go-chef/chef" 15 ) 16 17 func Provider() terraform.ResourceProvider { 18 return &schema.Provider{ 19 Schema: map[string]*schema.Schema{ 20 "server_url": { 21 Type: schema.TypeString, 22 Required: true, 23 DefaultFunc: schema.EnvDefaultFunc("CHEF_SERVER_URL", nil), 24 Description: "URL of the root of the target Chef server or organization.", 25 }, 26 "client_name": { 27 Type: schema.TypeString, 28 Required: true, 29 DefaultFunc: schema.EnvDefaultFunc("CHEF_CLIENT_NAME", nil), 30 Description: "Name of a registered client within the Chef server.", 31 }, 32 "private_key_pem": { 33 Type: schema.TypeString, 34 Optional: true, 35 DefaultFunc: providerPrivateKeyEnvDefault, 36 Deprecated: "Please use key_material instead", 37 Description: "PEM-formatted private key for client authentication.", 38 }, 39 "key_material": { 40 Type: schema.TypeString, 41 Optional: true, 42 DefaultFunc: schema.EnvDefaultFunc("CHEF_KEY_MATERIAL", ""), 43 }, 44 "allow_unverified_ssl": { 45 Type: schema.TypeBool, 46 Optional: true, 47 Description: "If set, the Chef client will permit unverifiable SSL certificates.", 48 }, 49 }, 50 51 ResourcesMap: map[string]*schema.Resource{ 52 //"chef_acl": resourceChefAcl(), 53 //"chef_client": resourceChefClient(), 54 //"chef_cookbook": resourceChefCookbook(), 55 "chef_data_bag": resourceChefDataBag(), 56 "chef_data_bag_item": resourceChefDataBagItem(), 57 "chef_environment": resourceChefEnvironment(), 58 "chef_node": resourceChefNode(), 59 "chef_role": resourceChefRole(), 60 }, 61 62 ConfigureFunc: providerConfigure, 63 } 64 } 65 66 func providerConfigure(d *schema.ResourceData) (interface{}, error) { 67 config := &chefc.Config{ 68 Name: d.Get("client_name").(string), 69 BaseURL: d.Get("server_url").(string), 70 SkipSSL: d.Get("allow_unverified_ssl").(bool), 71 Timeout: 10 * time.Second, 72 } 73 74 if v, ok := d.GetOk("private_key_pem"); ok { 75 config.Key = v.(string) 76 } 77 78 if v, ok := d.GetOk("key_material"); ok { 79 config.Key = v.(string) 80 } 81 82 return chefc.NewClient(config) 83 } 84 85 func providerPrivateKeyEnvDefault() (interface{}, error) { 86 if fn := os.Getenv("CHEF_PRIVATE_KEY_FILE"); fn != "" { 87 contents, err := ioutil.ReadFile(fn) 88 if err != nil { 89 return nil, err 90 } 91 return string(contents), nil 92 } 93 94 return nil, nil 95 } 96 97 func jsonStateFunc(value interface{}) string { 98 // Parse and re-stringify the JSON to make sure it's always kept 99 // in a normalized form. 100 in, ok := value.(string) 101 if !ok { 102 return "null" 103 } 104 var tmp map[string]interface{} 105 106 // Assuming the value must be valid JSON since it passed okay through 107 // our prepareDataBagItemContent function earlier. 108 json.Unmarshal([]byte(in), &tmp) 109 110 jsonValue, _ := json.Marshal(&tmp) 111 return string(jsonValue) 112 } 113 114 func runListEntryStateFunc(value interface{}) string { 115 // Recipes in run lists can either be naked, like "foo", or can 116 // be explicitly qualified as "recipe[foo]". Whichever form we use, 117 // the server will always normalize to the explicit form, 118 // so we'll normalize too and then we won't generate unnecessary 119 // diffs when we refresh. 120 in := value.(string) 121 if !strings.Contains(in, "[") { 122 return fmt.Sprintf("recipe[%s]", in) 123 } 124 return in 125 }