github.com/mmcquillan/packer@v1.1.1-0.20171009221028-c85cf0483a5d/builder/triton/access_config.go (about) 1 package triton 2 3 import ( 4 "errors" 5 "fmt" 6 "io/ioutil" 7 "os" 8 9 "github.com/hashicorp/packer/helper/communicator" 10 "github.com/hashicorp/packer/template/interpolate" 11 "github.com/joyent/triton-go" 12 "github.com/joyent/triton-go/authentication" 13 ) 14 15 // AccessConfig is for common configuration related to Triton access 16 type AccessConfig struct { 17 Endpoint string `mapstructure:"triton_url"` 18 Account string `mapstructure:"triton_account"` 19 KeyID string `mapstructure:"triton_key_id"` 20 KeyMaterial string `mapstructure:"triton_key_material"` 21 22 signer authentication.Signer 23 } 24 25 // Prepare performs basic validation on the AccessConfig and ensures we can sign 26 // a request. 27 func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { 28 var errs []error 29 30 if c.Endpoint == "" { 31 // Use Joyent public cloud as the default endpoint if none is specified 32 c.Endpoint = "https://us-sw-1.api.joyent.com" 33 } 34 35 if c.Account == "" { 36 errs = append(errs, errors.New("triton_account is required to use the triton builder")) 37 } 38 39 if c.KeyID == "" { 40 errs = append(errs, errors.New("triton_key_id is required to use the triton builder")) 41 } 42 43 if c.KeyMaterial == "" { 44 signer, err := c.createSSHAgentSigner() 45 if err != nil { 46 errs = append(errs, err) 47 } 48 c.signer = signer 49 } else { 50 signer, err := c.createPrivateKeySigner() 51 if err != nil { 52 errs = append(errs, err) 53 } 54 c.signer = signer 55 } 56 57 if len(errs) > 0 { 58 return errs 59 } 60 61 return nil 62 } 63 64 func (c *AccessConfig) createSSHAgentSigner() (authentication.Signer, error) { 65 signer, err := authentication.NewSSHAgentSigner(c.KeyID, c.Account) 66 if err != nil { 67 return nil, fmt.Errorf("Error creating Triton request signer: %s", err) 68 } 69 70 // Ensure we can sign a request 71 _, err = signer.Sign("Wed, 26 Apr 2017 16:01:11 UTC") 72 if err != nil { 73 return nil, fmt.Errorf("Error signing test request: %s", err) 74 } 75 76 return signer, nil 77 } 78 79 func (c *AccessConfig) createPrivateKeySigner() (authentication.Signer, error) { 80 var privateKeyMaterial []byte 81 var err error 82 83 // Check for keyMaterial being a file path 84 if _, err = os.Stat(c.KeyMaterial); err != nil { 85 privateKeyMaterial = []byte(c.KeyMaterial) 86 } else { 87 privateKeyMaterial, err = ioutil.ReadFile(c.KeyMaterial) 88 if err != nil { 89 return nil, fmt.Errorf("Error reading key material from path '%s': %s", 90 c.KeyMaterial, err) 91 } 92 } 93 94 // Create signer 95 signer, err := authentication.NewPrivateKeySigner(c.KeyID, privateKeyMaterial, c.Account) 96 if err != nil { 97 return nil, fmt.Errorf("Error creating Triton request signer: %s", err) 98 } 99 100 // Ensure we can sign a request 101 _, err = signer.Sign("Wed, 26 Apr 2017 16:01:11 UTC") 102 if err != nil { 103 return nil, fmt.Errorf("Error signing test request: %s", err) 104 } 105 106 return signer, nil 107 } 108 109 func (c *AccessConfig) CreateTritonClient() (*triton.Client, error) { 110 return triton.NewClient(c.Endpoint, c.Account, c.signer) 111 } 112 113 func (c *AccessConfig) Comm() communicator.Config { 114 return communicator.Config{} 115 }