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