github.phpd.cn/hashicorp/packer@v1.3.2/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/errwrap" 10 "github.com/hashicorp/packer/helper/communicator" 11 "github.com/hashicorp/packer/template/interpolate" 12 tgo "github.com/joyent/triton-go" 13 "github.com/joyent/triton-go/authentication" 14 "github.com/joyent/triton-go/compute" 15 "github.com/joyent/triton-go/network" 16 ) 17 18 // AccessConfig is for common configuration related to Triton access 19 type AccessConfig struct { 20 Endpoint string `mapstructure:"triton_url"` 21 Account string `mapstructure:"triton_account"` 22 Username string `mapstructure:"triton_user"` 23 KeyID string `mapstructure:"triton_key_id"` 24 KeyMaterial string `mapstructure:"triton_key_material"` 25 InsecureSkipTLSVerify bool `mapstructure:"insecure_skip_tls_verify"` 26 27 signer authentication.Signer 28 } 29 30 // Prepare performs basic validation on the AccessConfig and ensures we can sign 31 // a request. 32 func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { 33 var errs []error 34 35 if c.Endpoint == "" { 36 // Use Joyent public cloud as the default endpoint if none is specified 37 c.Endpoint = "https://us-sw-1.api.joyent.com" 38 } 39 40 if c.Account == "" { 41 errs = append(errs, errors.New("triton_account is required to use the triton builder")) 42 } 43 44 if c.KeyID == "" { 45 errs = append(errs, errors.New("triton_key_id is required to use the triton builder")) 46 } 47 48 if c.KeyMaterial == "" { 49 signer, err := c.createSSHAgentSigner() 50 if err != nil { 51 errs = append(errs, err) 52 } 53 c.signer = signer 54 } else { 55 signer, err := c.createPrivateKeySigner() 56 if err != nil { 57 errs = append(errs, err) 58 } 59 c.signer = signer 60 } 61 62 if len(errs) > 0 { 63 return errs 64 } 65 66 return nil 67 } 68 69 func (c *AccessConfig) createSSHAgentSigner() (authentication.Signer, error) { 70 input := authentication.SSHAgentSignerInput{ 71 KeyID: c.KeyID, 72 AccountName: c.Account, 73 Username: c.Username, 74 } 75 signer, err := authentication.NewSSHAgentSigner(input) 76 if err != nil { 77 return nil, fmt.Errorf("Error creating Triton request signer: %s", err) 78 } 79 80 // Ensure we can sign a request 81 _, err = signer.Sign("Wed, 26 Apr 2017 16:01:11 UTC") 82 if err != nil { 83 return nil, fmt.Errorf("Error signing test request: %s", err) 84 } 85 86 return signer, nil 87 } 88 89 func (c *AccessConfig) createPrivateKeySigner() (authentication.Signer, error) { 90 var privateKeyMaterial []byte 91 var err error 92 93 // Check for keyMaterial being a file path 94 if _, err = os.Stat(c.KeyMaterial); err != nil { 95 privateKeyMaterial = []byte(c.KeyMaterial) 96 } else { 97 privateKeyMaterial, err = ioutil.ReadFile(c.KeyMaterial) 98 if err != nil { 99 return nil, fmt.Errorf("Error reading key material from path '%s': %s", 100 c.KeyMaterial, err) 101 } 102 } 103 104 input := authentication.PrivateKeySignerInput{ 105 KeyID: c.KeyID, 106 AccountName: c.Account, 107 Username: c.Username, 108 PrivateKeyMaterial: privateKeyMaterial, 109 } 110 111 signer, err := authentication.NewPrivateKeySigner(input) 112 if err != nil { 113 return nil, fmt.Errorf("Error creating Triton request signer: %s", err) 114 } 115 116 // Ensure we can sign a request 117 _, err = signer.Sign("Wed, 26 Apr 2017 16:01:11 UTC") 118 if err != nil { 119 return nil, fmt.Errorf("Error signing test request: %s", err) 120 } 121 122 return signer, nil 123 } 124 125 func (c *AccessConfig) CreateTritonClient() (*Client, error) { 126 127 config := &tgo.ClientConfig{ 128 AccountName: c.Account, 129 TritonURL: c.Endpoint, 130 Username: c.Username, 131 Signers: []authentication.Signer{c.signer}, 132 } 133 134 return &Client{ 135 config: config, 136 insecureSkipTLSVerify: c.InsecureSkipTLSVerify, 137 }, nil 138 } 139 140 type Client struct { 141 config *tgo.ClientConfig 142 insecureSkipTLSVerify bool 143 } 144 145 func (c *Client) Compute() (*compute.ComputeClient, error) { 146 computeClient, err := compute.NewClient(c.config) 147 if err != nil { 148 return nil, errwrap.Wrapf("Error Creating Triton Compute Client: {{err}}", err) 149 } 150 151 if c.insecureSkipTLSVerify { 152 computeClient.Client.InsecureSkipTLSVerify() 153 } 154 155 return computeClient, nil 156 } 157 158 func (c *Client) Network() (*network.NetworkClient, error) { 159 networkClient, err := network.NewClient(c.config) 160 if err != nil { 161 return nil, errwrap.Wrapf("Error Creating Triton Network Client: {{err}}", err) 162 } 163 164 if c.insecureSkipTLSVerify { 165 networkClient.Client.InsecureSkipTLSVerify() 166 } 167 168 return networkClient, nil 169 } 170 171 func (c *AccessConfig) Comm() communicator.Config { 172 return communicator.Config{} 173 }