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  }