Add support for Google subnetworks. Closes #3062. Fixes an issue with how packer populates instances metadata. Closes #3181

This commit is contained in:
Matt Morrison 2016-02-11 17:31:46 +13:00
parent 2a46f4001c
commit 942aaa7a85
4 changed files with 33 additions and 1 deletions

View File

@ -31,6 +31,7 @@ type Config struct {
MachineType string `mapstructure:"machine_type"`
Metadata map[string]string `mapstructure:"metadata"`
Network string `mapstructure:"network"`
Subnetwork string `mapstructure:"subnetwork"`
Address string `mapstructure:"address"`
Preemptible bool `mapstructure:"preemptible"`
SourceImage string `mapstructure:"source_image"`
@ -38,6 +39,7 @@ type Config struct {
RawStateTimeout string `mapstructure:"state_timeout"`
Tags []string `mapstructure:"tags"`
UseInternalIP bool `mapstructure:"use_internal_ip"`
Region string `mapstructure:"region"`
Zone string `mapstructure:"zone"`
account accountFile
@ -125,6 +127,11 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
errs = packer.MultiErrorAppend(
errs, errors.New("a zone must be specified"))
}
if c.Region == "" && len(c.Zone) > 2 {
// get region from Zone
region := c.Zone[:len(c.Zone)-2]
c.Region = region
}
stateTimeout, err := time.ParseDuration(c.RawStateTimeout)
if err != nil {

View File

@ -47,8 +47,10 @@ type InstanceConfig struct {
Metadata map[string]string
Name string
Network string
Subnetwork string
Address string
Preemptible bool
Tags []string
Region string
Zone string
}

View File

@ -215,6 +215,25 @@ func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) {
return nil, err
}
// Subnetwork
// Validate Subnetwork config now that we have some info about the network
if !network.AutoCreateSubnetworks && len(network.Subnetworks) > 0 {
// Network appears to be in "custom" mode, so a subnetwork is required
if c.Subnetwork == "" {
return nil, fmt.Errorf("a subnetwork must be specified")
}
}
// Get the subnetwork
subnetworkSelfLink := ""
if c.Subnetwork != "" {
d.ui.Message(fmt.Sprintf("Loading subnetwork: %s for region: %s", c.Subnetwork, c.Region))
subnetwork, err := d.service.Subnetworks.Get(d.projectId, c.Region, c.Subnetwork).Do()
if err != nil {
return nil, err
}
subnetworkSelfLink = subnetwork.SelfLink
}
// If given a regional ip, get it
accessconfig := compute.AccessConfig{
Name: "AccessConfig created by Packer",
@ -235,9 +254,10 @@ func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) {
// Build up the metadata
metadata := make([]*compute.MetadataItems, len(c.Metadata))
for k, v := range c.Metadata {
vCopy := v
metadata = append(metadata, &compute.MetadataItems{
Key: k,
Value: &v,
Value: &vCopy,
})
}
@ -268,6 +288,7 @@ func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) {
&accessconfig,
},
Network: network.SelfLink,
Subnetwork: subnetworkSelfLink,
},
},
Scheduling: &compute.Scheduling{

View File

@ -59,9 +59,11 @@ func (s *StepCreateInstance) Run(state multistep.StateBag) multistep.StepAction
Metadata: config.getInstanceMetadata(sshPublicKey),
Name: name,
Network: config.Network,
Subnetwork: config.Subnetwork,
Address: config.Address,
Preemptible: config.Preemptible,
Tags: config.Tags,
Region: config.Region,
Zone: config.Zone,
})