github.com/tonnydourado/packer@v0.6.1-0.20140701134019-5d0cd9676a37/builder/amazon/common/ami_config.go (about)

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