github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/builtin/providers/triton/provider.go (about) 1 package triton 2 3 import ( 4 "crypto/md5" 5 "encoding/base64" 6 "errors" 7 "sort" 8 "time" 9 10 "github.com/hashicorp/errwrap" 11 "github.com/hashicorp/go-multierror" 12 "github.com/hashicorp/terraform/helper/schema" 13 "github.com/hashicorp/terraform/terraform" 14 "github.com/joyent/triton-go" 15 "github.com/joyent/triton-go/authentication" 16 ) 17 18 // Provider returns a terraform.ResourceProvider. 19 func Provider() terraform.ResourceProvider { 20 return &schema.Provider{ 21 Schema: map[string]*schema.Schema{ 22 "account": { 23 Type: schema.TypeString, 24 Required: true, 25 DefaultFunc: schema.MultiEnvDefaultFunc([]string{"TRITON_ACCOUNT", "SDC_ACCOUNT"}, ""), 26 }, 27 28 "url": { 29 Type: schema.TypeString, 30 Required: true, 31 DefaultFunc: schema.MultiEnvDefaultFunc([]string{"TRITON_URL", "SDC_URL"}, "https://us-west-1.api.joyentcloud.com"), 32 }, 33 34 "key_material": { 35 Type: schema.TypeString, 36 Optional: true, 37 DefaultFunc: schema.MultiEnvDefaultFunc([]string{"TRITON_KEY_MATERIAL", "SDC_KEY_MATERIAL"}, ""), 38 }, 39 40 "key_id": { 41 Type: schema.TypeString, 42 Required: true, 43 DefaultFunc: schema.MultiEnvDefaultFunc([]string{"TRITON_KEY_ID", "SDC_KEY_ID"}, ""), 44 }, 45 46 "insecure_skip_tls_verify": { 47 Type: schema.TypeBool, 48 Optional: true, 49 DefaultFunc: schema.EnvDefaultFunc("TRITON_SKIP_TLS_VERIFY", ""), 50 }, 51 }, 52 53 ResourcesMap: map[string]*schema.Resource{ 54 "triton_firewall_rule": resourceFirewallRule(), 55 "triton_machine": resourceMachine(), 56 "triton_key": resourceKey(), 57 "triton_vlan": resourceVLAN(), 58 "triton_fabric": resourceFabric(), 59 }, 60 ConfigureFunc: providerConfigure, 61 } 62 } 63 64 type Config struct { 65 Account string 66 KeyMaterial string 67 KeyID string 68 URL string 69 InsecureSkipTLSVerify bool 70 } 71 72 func (c Config) validate() error { 73 var err *multierror.Error 74 75 if c.URL == "" { 76 err = multierror.Append(err, errors.New("URL must be configured for the Triton provider")) 77 } 78 if c.KeyID == "" { 79 err = multierror.Append(err, errors.New("Key ID must be configured for the Triton provider")) 80 } 81 if c.Account == "" { 82 err = multierror.Append(err, errors.New("Account must be configured for the Triton provider")) 83 } 84 85 return err.ErrorOrNil() 86 } 87 88 func (c Config) getTritonClient() (*triton.Client, error) { 89 var signer authentication.Signer 90 var err error 91 if c.KeyMaterial == "" { 92 signer, err = authentication.NewSSHAgentSigner(c.KeyID, c.Account) 93 if err != nil { 94 return nil, errwrap.Wrapf("Error Creating SSH Agent Signer: {{err}}", err) 95 } 96 } else { 97 signer, err = authentication.NewPrivateKeySigner(c.KeyID, []byte(c.KeyMaterial), c.Account) 98 if err != nil { 99 return nil, errwrap.Wrapf("Error Creating SSH Private Key Signer: {{err}}", err) 100 } 101 } 102 103 client, err := triton.NewClient(c.URL, c.Account, signer) 104 if err != nil { 105 return nil, errwrap.Wrapf("Error Creating Triton Client: {{err}}", err) 106 } 107 108 if c.InsecureSkipTLSVerify { 109 client.InsecureSkipTLSVerify() 110 } 111 112 return client, nil 113 } 114 115 func providerConfigure(d *schema.ResourceData) (interface{}, error) { 116 config := Config{ 117 Account: d.Get("account").(string), 118 URL: d.Get("url").(string), 119 KeyID: d.Get("key_id").(string), 120 121 InsecureSkipTLSVerify: d.Get("insecure_skip_tls_verify").(bool), 122 } 123 124 if keyMaterial, ok := d.GetOk("key_material"); ok { 125 config.KeyMaterial = keyMaterial.(string) 126 } 127 128 if err := config.validate(); err != nil { 129 return nil, err 130 } 131 132 client, err := config.getTritonClient() 133 if err != nil { 134 return nil, err 135 } 136 137 return client, nil 138 } 139 140 func resourceExists(resource interface{}, err error) (bool, error) { 141 if err != nil { 142 if triton.IsResourceNotFound(err) { 143 return false, nil 144 } 145 146 return false, err 147 } 148 149 return resource != nil, nil 150 } 151 152 func stableMapHash(input map[string]string) string { 153 keys := make([]string, 0, len(input)) 154 for k := range input { 155 keys = append(keys, k) 156 } 157 sort.Strings(keys) 158 159 hash := md5.New() 160 for _, key := range keys { 161 hash.Write([]byte(key)) 162 hash.Write([]byte(input[key])) 163 } 164 165 return base64.StdEncoding.EncodeToString(hash.Sum([]byte{})) 166 } 167 168 var fastResourceTimeout = &schema.ResourceTimeout{ 169 Create: schema.DefaultTimeout(1 * time.Minute), 170 Read: schema.DefaultTimeout(30 * time.Second), 171 Update: schema.DefaultTimeout(1 * time.Minute), 172 Delete: schema.DefaultTimeout(1 * time.Minute), 173 } 174 175 var slowResourceTimeout = &schema.ResourceTimeout{ 176 Create: schema.DefaultTimeout(10 * time.Minute), 177 Read: schema.DefaultTimeout(30 * time.Second), 178 Update: schema.DefaultTimeout(10 * time.Minute), 179 Delete: schema.DefaultTimeout(10 * time.Minute), 180 }