github.com/amanya/packer@v0.12.1-0.20161117214323-902ac5ab2eb6/builder/cloudstack/config.go (about)

     1  package cloudstack
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  	"time"
     8  
     9  	"github.com/mitchellh/packer/common"
    10  	"github.com/mitchellh/packer/common/uuid"
    11  	"github.com/mitchellh/packer/helper/communicator"
    12  	"github.com/mitchellh/packer/helper/config"
    13  	"github.com/mitchellh/packer/packer"
    14  	"github.com/mitchellh/packer/template/interpolate"
    15  )
    16  
    17  // Config holds all the details needed to configure the builder.
    18  type Config struct {
    19  	common.PackerConfig `mapstructure:",squash"`
    20  	Comm                communicator.Config `mapstructure:",squash"`
    21  
    22  	APIURL       string        `mapstructure:"api_url"`
    23  	APIKey       string        `mapstructure:"api_key"`
    24  	SecretKey    string        `mapstructure:"secret_key"`
    25  	AsyncTimeout time.Duration `mapstructure:"async_timeout"`
    26  	HTTPGetOnly  bool          `mapstructure:"http_get_only"`
    27  	SSLNoVerify  bool          `mapstructure:"ssl_no_verify"`
    28  
    29  	DiskOffering      string   `mapstructure:"disk_offering"`
    30  	DiskSize          int64    `mapstructure:"disk_size"`
    31  	CIDRList          []string `mapstructure:"cidr_list"`
    32  	Hypervisor        string   `mapstructure:"hypervisor"`
    33  	InstanceName      string   `mapstructure:"instance_name"`
    34  	Keypair           string   `mapstructure:"keypair"`
    35  	Network           string   `mapstructure:"network"`
    36  	Project           string   `mapstructure:"project"`
    37  	PublicIPAddress   string   `mapstructure:"public_ip_address"`
    38  	ServiceOffering   string   `mapstructure:"service_offering"`
    39  	SourceTemplate    string   `mapstructure:"source_template"`
    40  	SourceISO         string   `mapstructure:"source_iso"`
    41  	UserData          string   `mapstructure:"user_data"`
    42  	UserDataFile      string   `mapstructure:"user_data_file"`
    43  	UseLocalIPAddress bool     `mapstructure:"use_local_ip_address"`
    44  	Zone              string   `mapstructure:"zone"`
    45  
    46  	TemplateName            string `mapstructure:"template_name"`
    47  	TemplateDisplayText     string `mapstructure:"template_display_text"`
    48  	TemplateOS              string `mapstructure:"template_os"`
    49  	TemplateFeatured        bool   `mapstructure:"template_featured"`
    50  	TemplatePublic          bool   `mapstructure:"template_public"`
    51  	TemplatePasswordEnabled bool   `mapstructure:"template_password_enabled"`
    52  	TemplateRequiresHVM     bool   `mapstructure:"template_requires_hvm"`
    53  	TemplateScalable        bool   `mapstructure:"template_scalable"`
    54  	TemplateTag             string `mapstructure:"template_tag"`
    55  
    56  	ctx            interpolate.Context
    57  	hostAddress    string // The host address used by the communicators.
    58  	instanceSource string // This can be either a template ID or an ISO ID.
    59  }
    60  
    61  // NewConfig parses and validates the given config.
    62  func NewConfig(raws ...interface{}) (*Config, error) {
    63  	c := new(Config)
    64  	err := config.Decode(c, &config.DecodeOpts{
    65  		Interpolate:        true,
    66  		InterpolateContext: &c.ctx,
    67  	}, raws...)
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  
    72  	var errs *packer.MultiError
    73  
    74  	// Set some defaults.
    75  	if c.AsyncTimeout == 0 {
    76  		c.AsyncTimeout = 30 * time.Minute
    77  	}
    78  
    79  	if c.InstanceName == "" {
    80  		c.InstanceName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID())
    81  	}
    82  
    83  	if c.TemplateName == "" {
    84  		name, err := interpolate.Render("packer-{{timestamp}}", nil)
    85  		if err != nil {
    86  			errs = packer.MultiErrorAppend(errs,
    87  				fmt.Errorf("Unable to parse template name: %s ", err))
    88  		}
    89  
    90  		c.TemplateName = name
    91  	}
    92  
    93  	if c.TemplateDisplayText == "" {
    94  		c.TemplateDisplayText = c.TemplateName
    95  	}
    96  
    97  	// Process required parameters.
    98  	if c.APIURL == "" {
    99  		errs = packer.MultiErrorAppend(errs, errors.New("a api_url must be specified"))
   100  	}
   101  
   102  	if c.APIKey == "" {
   103  		errs = packer.MultiErrorAppend(errs, errors.New("a api_key must be specified"))
   104  	}
   105  
   106  	if c.SecretKey == "" {
   107  		errs = packer.MultiErrorAppend(errs, errors.New("a secret_key must be specified"))
   108  	}
   109  
   110  	if len(c.CIDRList) == 0 && !c.UseLocalIPAddress {
   111  		errs = packer.MultiErrorAppend(errs, errors.New("a cidr_list must be specified"))
   112  	}
   113  
   114  	if c.Network == "" {
   115  		errs = packer.MultiErrorAppend(errs, errors.New("a network must be specified"))
   116  	}
   117  
   118  	if c.ServiceOffering == "" {
   119  		errs = packer.MultiErrorAppend(errs, errors.New("a service_offering must be specified"))
   120  	}
   121  
   122  	if c.SourceISO == "" && c.SourceTemplate == "" {
   123  		errs = packer.MultiErrorAppend(
   124  			errs, errors.New("either source_iso or source_template must be specified"))
   125  	}
   126  
   127  	if c.SourceISO != "" && c.SourceTemplate != "" {
   128  		errs = packer.MultiErrorAppend(
   129  			errs, errors.New("only one of source_iso or source_template can be specified"))
   130  	}
   131  
   132  	if c.SourceISO != "" && c.DiskOffering == "" {
   133  		errs = packer.MultiErrorAppend(
   134  			errs, errors.New("a disk_offering must be specified when using source_iso"))
   135  	}
   136  
   137  	if c.SourceISO != "" && c.Hypervisor == "" {
   138  		errs = packer.MultiErrorAppend(
   139  			errs, errors.New("a hypervisor must be specified when using source_iso"))
   140  	}
   141  
   142  	if c.TemplateOS == "" {
   143  		errs = packer.MultiErrorAppend(errs, errors.New("a template_os must be specified"))
   144  	}
   145  
   146  	if c.UserData != "" && c.UserDataFile != "" {
   147  		errs = packer.MultiErrorAppend(
   148  			errs, errors.New("only one of user_data or user_data_file can be specified"))
   149  	}
   150  
   151  	if c.UserDataFile != "" {
   152  		if _, err := os.Stat(c.UserDataFile); err != nil {
   153  			errs = packer.MultiErrorAppend(
   154  				errs, fmt.Errorf("user_data_file not found: %s", c.UserDataFile))
   155  		}
   156  	}
   157  
   158  	if c.Zone == "" {
   159  		errs = packer.MultiErrorAppend(errs, errors.New("a zone must be specified"))
   160  	}
   161  
   162  	if es := c.Comm.Prepare(&c.ctx); len(es) > 0 {
   163  		errs = packer.MultiErrorAppend(errs, es...)
   164  	}
   165  
   166  	// Check for errors and return if we have any.
   167  	if errs != nil && len(errs.Errors) > 0 {
   168  		return nil, errs
   169  	}
   170  
   171  	return c, nil
   172  }