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