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  }