github.com/daniellockard/packer@v0.7.6-0.20141210173435-5a9390934716/builder/amazon/common/ami_config.go (about)

     1  package common
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/mitchellh/goamz/aws"
     7  	"github.com/mitchellh/packer/packer"
     8  )
     9  
    10  // AMIConfig is for common configuration related to creating AMIs.
    11  type AMIConfig struct {
    12  	AMIName               string            `mapstructure:"ami_name"`
    13  	AMIDescription        string            `mapstructure:"ami_description"`
    14  	AMIVirtType           string            `mapstructure:"ami_virtualization_type"`
    15  	AMIUsers              []string          `mapstructure:"ami_users"`
    16  	AMIGroups             []string          `mapstructure:"ami_groups"`
    17  	AMIProductCodes       []string          `mapstructure:"ami_product_codes"`
    18  	AMIRegions            []string          `mapstructure:"ami_regions"`
    19  	AMITags               map[string]string `mapstructure:"tags"`
    20  	AMIEnhancedNetworking bool              `mapstructure:"enhanced_networking"`
    21  }
    22  
    23  func (c *AMIConfig) Prepare(t *packer.ConfigTemplate) []error {
    24  	if t == nil {
    25  		var err error
    26  		t, err = packer.NewConfigTemplate()
    27  		if err != nil {
    28  			return []error{err}
    29  		}
    30  	}
    31  
    32  	templates := map[string]*string{
    33  		"ami_name":                &c.AMIName,
    34  		"ami_description":         &c.AMIDescription,
    35  		"ami_virtualization_type": &c.AMIVirtType,
    36  	}
    37  
    38  	errs := make([]error, 0)
    39  	for n, ptr := range templates {
    40  		var err error
    41  		*ptr, err = t.Process(*ptr, nil)
    42  		if err != nil {
    43  			errs = append(
    44  				errs, fmt.Errorf("Error processing %s: %s", n, err))
    45  		}
    46  	}
    47  
    48  	sliceTemplates := map[string][]string{
    49  		"ami_users":         c.AMIUsers,
    50  		"ami_groups":        c.AMIGroups,
    51  		"ami_product_codes": c.AMIProductCodes,
    52  		"ami_regions":       c.AMIRegions,
    53  	}
    54  
    55  	for n, slice := range sliceTemplates {
    56  		for i, elem := range slice {
    57  			var err error
    58  			slice[i], err = t.Process(elem, nil)
    59  			if err != nil {
    60  				errs = append(
    61  					errs, fmt.Errorf("Error processing %s[%d]: %s", n, i, err))
    62  			}
    63  		}
    64  	}
    65  
    66  	if c.AMIName == "" {
    67  		errs = append(errs, fmt.Errorf("ami_name must be specified"))
    68  	}
    69  
    70  	if len(c.AMIRegions) > 0 {
    71  		regionSet := make(map[string]struct{})
    72  		regions := make([]string, 0, len(c.AMIRegions))
    73  
    74  		for _, region := range c.AMIRegions {
    75  			// If we already saw the region, then don't look again
    76  			if _, ok := regionSet[region]; ok {
    77  				continue
    78  			}
    79  
    80  			// Mark that we saw the region
    81  			regionSet[region] = struct{}{}
    82  
    83  			// Verify the region is real
    84  			if _, ok := aws.Regions[region]; !ok {
    85  				errs = append(errs, fmt.Errorf("Unknown region: %s", region))
    86  				continue
    87  			}
    88  
    89  			regions = append(regions, region)
    90  		}
    91  
    92  		c.AMIRegions = regions
    93  	}
    94  
    95  	newTags := make(map[string]string)
    96  	for k, v := range c.AMITags {
    97  		k, err := t.Process(k, nil)
    98  		if err != nil {
    99  			errs = append(errs,
   100  				fmt.Errorf("Error processing tag key %s: %s", k, err))
   101  			continue
   102  		}
   103  
   104  		v, err := t.Process(v, nil)
   105  		if err != nil {
   106  			errs = append(errs,
   107  				fmt.Errorf("Error processing tag value '%s': %s", v, err))
   108  			continue
   109  		}
   110  
   111  		newTags[k] = v
   112  	}
   113  
   114  	c.AMITags = newTags
   115  
   116  	if len(errs) > 0 {
   117  		return errs
   118  	}
   119  
   120  	return nil
   121  }