github.com/askholme/packer@v0.7.2-0.20140924152349-70d9566a6852/builder/googlecompute/config.go (about)

     1  package googlecompute
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/mitchellh/packer/common"
     9  	"github.com/mitchellh/packer/common/uuid"
    10  	"github.com/mitchellh/packer/packer"
    11  )
    12  
    13  // Config is the configuration structure for the GCE builder. It stores
    14  // both the publicly settable state as well as the privately generated
    15  // state of the config object.
    16  type Config struct {
    17  	common.PackerConfig `mapstructure:",squash"`
    18  
    19  	AccountFile       string `mapstructure:"account_file"`
    20  	ClientSecretsFile string `mapstructure:"client_secrets_file"`
    21  	ProjectId         string `mapstructure:"project_id"`
    22  
    23  	BucketName           string            `mapstructure:"bucket_name"`
    24  	DiskSizeGb           int64             `mapstructure:"disk_size"`
    25  	ImageName            string            `mapstructure:"image_name"`
    26  	ImageDescription     string            `mapstructure:"image_description"`
    27  	InstanceName         string            `mapstructure:"instance_name"`
    28  	MachineType          string            `mapstructure:"machine_type"`
    29  	Metadata             map[string]string `mapstructure:"metadata"`
    30  	Network              string            `mapstructure:"network"`
    31  	SourceImage          string            `mapstructure:"source_image"`
    32  	SourceImageProjectId string            `mapstructure:"source_image_project_id"`
    33  	SSHUsername          string            `mapstructure:"ssh_username"`
    34  	SSHPort              uint              `mapstructure:"ssh_port"`
    35  	RawSSHTimeout        string            `mapstructure:"ssh_timeout"`
    36  	RawStateTimeout      string            `mapstructure:"state_timeout"`
    37  	Tags                 []string          `mapstructure:"tags"`
    38  	Zone                 string            `mapstructure:"zone"`
    39  
    40  	account         accountFile
    41  	clientSecrets   clientSecretsFile
    42  	instanceName    string
    43  	privateKeyBytes []byte
    44  	sshTimeout      time.Duration
    45  	stateTimeout    time.Duration
    46  	tpl             *packer.ConfigTemplate
    47  }
    48  
    49  func NewConfig(raws ...interface{}) (*Config, []string, error) {
    50  	c := new(Config)
    51  	md, err := common.DecodeConfig(c, raws...)
    52  	if err != nil {
    53  		return nil, nil, err
    54  	}
    55  
    56  	c.tpl, err = packer.NewConfigTemplate()
    57  	if err != nil {
    58  		return nil, nil, err
    59  	}
    60  	c.tpl.UserVars = c.PackerUserVars
    61  
    62  	// Prepare the errors
    63  	errs := common.CheckUnusedConfig(md)
    64  
    65  	// Set defaults.
    66  	if c.Network == "" {
    67  		c.Network = "default"
    68  	}
    69  
    70  	if c.DiskSizeGb == 0 {
    71  		c.DiskSizeGb = 10
    72  	}
    73  
    74  	if c.ImageDescription == "" {
    75  		c.ImageDescription = "Created by Packer"
    76  	}
    77  
    78  	if c.ImageName == "" {
    79  		c.ImageName = "packer-{{timestamp}}"
    80  	}
    81  
    82  	if c.InstanceName == "" {
    83  		c.InstanceName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID())
    84  	}
    85  
    86  	if c.MachineType == "" {
    87  		c.MachineType = "n1-standard-1"
    88  	}
    89  
    90  	if c.RawSSHTimeout == "" {
    91  		c.RawSSHTimeout = "5m"
    92  	}
    93  
    94  	if c.RawStateTimeout == "" {
    95  		c.RawStateTimeout = "5m"
    96  	}
    97  
    98  	if c.SSHUsername == "" {
    99  		c.SSHUsername = "root"
   100  	}
   101  
   102  	if c.SSHPort == 0 {
   103  		c.SSHPort = 22
   104  	}
   105  
   106  	// Process Templates
   107  	templates := map[string]*string{
   108  		"account_file":        &c.AccountFile,
   109  		"client_secrets_file": &c.ClientSecretsFile,
   110  
   111  		"bucket_name":             &c.BucketName,
   112  		"image_name":              &c.ImageName,
   113  		"image_description":       &c.ImageDescription,
   114  		"instance_name":           &c.InstanceName,
   115  		"machine_type":            &c.MachineType,
   116  		"network":                 &c.Network,
   117  		"project_id":              &c.ProjectId,
   118  		"source_image":            &c.SourceImage,
   119  		"source_image_project_id": &c.SourceImageProjectId,
   120  		"ssh_username":            &c.SSHUsername,
   121  		"ssh_timeout":             &c.RawSSHTimeout,
   122  		"state_timeout":           &c.RawStateTimeout,
   123  		"zone":                    &c.Zone,
   124  	}
   125  
   126  	for n, ptr := range templates {
   127  		var err error
   128  		*ptr, err = c.tpl.Process(*ptr, nil)
   129  		if err != nil {
   130  			errs = packer.MultiErrorAppend(
   131  				errs, fmt.Errorf("Error processing %s: %s", n, err))
   132  		}
   133  	}
   134  
   135  	// Process required parameters.
   136  	if c.BucketName == "" {
   137  		errs = packer.MultiErrorAppend(
   138  			errs, errors.New("a bucket_name must be specified"))
   139  	}
   140  
   141  	if c.AccountFile == "" {
   142  		errs = packer.MultiErrorAppend(
   143  			errs, errors.New("an account_file must be specified"))
   144  	}
   145  
   146  	if c.ClientSecretsFile == "" {
   147  		errs = packer.MultiErrorAppend(
   148  			errs, errors.New("a client_secrets_file must be specified"))
   149  	}
   150  
   151  	if c.ProjectId == "" {
   152  		errs = packer.MultiErrorAppend(
   153  			errs, errors.New("a project_id must be specified"))
   154  	}
   155  
   156  	if c.SourceImage == "" {
   157  		errs = packer.MultiErrorAppend(
   158  			errs, errors.New("a source_image must be specified"))
   159  	}
   160  
   161  	if c.Zone == "" {
   162  		errs = packer.MultiErrorAppend(
   163  			errs, errors.New("a zone must be specified"))
   164  	}
   165  
   166  	// Process timeout settings.
   167  	sshTimeout, err := time.ParseDuration(c.RawSSHTimeout)
   168  	if err != nil {
   169  		errs = packer.MultiErrorAppend(
   170  			errs, fmt.Errorf("Failed parsing ssh_timeout: %s", err))
   171  	}
   172  	c.sshTimeout = sshTimeout
   173  
   174  	stateTimeout, err := time.ParseDuration(c.RawStateTimeout)
   175  	if err != nil {
   176  		errs = packer.MultiErrorAppend(
   177  			errs, fmt.Errorf("Failed parsing state_timeout: %s", err))
   178  	}
   179  	c.stateTimeout = stateTimeout
   180  
   181  	if c.AccountFile != "" {
   182  		if err := loadJSON(&c.account, c.AccountFile); err != nil {
   183  			errs = packer.MultiErrorAppend(
   184  				errs, fmt.Errorf("Failed parsing account file: %s", err))
   185  		}
   186  	}
   187  
   188  	if c.ClientSecretsFile != "" {
   189  		if err := loadJSON(&c.clientSecrets, c.ClientSecretsFile); err != nil {
   190  			errs = packer.MultiErrorAppend(
   191  				errs, fmt.Errorf("Failed parsing client secrets file: %s", err))
   192  		}
   193  	}
   194  
   195  	// Check for any errors.
   196  	if errs != nil && len(errs.Errors) > 0 {
   197  		return nil, nil, errs
   198  	}
   199  
   200  	return c, nil, nil
   201  }