github.com/StackPointCloud/packer@v0.10.2-0.20180716202532-b28098e0f79b/builder/openstack/run_config.go (about) 1 package openstack 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/hashicorp/packer/common/uuid" 8 "github.com/hashicorp/packer/helper/communicator" 9 "github.com/hashicorp/packer/template/interpolate" 10 ) 11 12 // RunConfig contains configuration for running an instance from a source 13 // image and details on how to access that launched image. 14 type RunConfig struct { 15 Comm communicator.Config `mapstructure:",squash"` 16 SSHKeyPairName string `mapstructure:"ssh_keypair_name"` 17 TemporaryKeyPairName string `mapstructure:"temporary_key_pair_name"` 18 SSHInterface string `mapstructure:"ssh_interface"` 19 SSHIPVersion string `mapstructure:"ssh_ip_version"` 20 21 SourceImage string `mapstructure:"source_image"` 22 SourceImageName string `mapstructure:"source_image_name"` 23 Flavor string `mapstructure:"flavor"` 24 AvailabilityZone string `mapstructure:"availability_zone"` 25 RackconnectWait bool `mapstructure:"rackconnect_wait"` 26 FloatingIpPool string `mapstructure:"floating_ip_pool"` 27 FloatingIp string `mapstructure:"floating_ip"` 28 ReuseIps bool `mapstructure:"reuse_ips"` 29 SecurityGroups []string `mapstructure:"security_groups"` 30 Networks []string `mapstructure:"networks"` 31 UserData string `mapstructure:"user_data"` 32 UserDataFile string `mapstructure:"user_data_file"` 33 InstanceName string `mapstructure:"instance_name"` 34 InstanceMetadata map[string]string `mapstructure:"instance_metadata"` 35 36 ConfigDrive bool `mapstructure:"config_drive"` 37 38 // Not really used, but here for BC 39 OpenstackProvider string `mapstructure:"openstack_provider"` 40 UseFloatingIp bool `mapstructure:"use_floating_ip"` 41 } 42 43 func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { 44 // If we are not given an explicit ssh_keypair_name or 45 // ssh_private_key_file, then create a temporary one, but only if the 46 // temporary_key_pair_name has not been provided and we are not using 47 // ssh_password. 48 if c.SSHKeyPairName == "" && c.TemporaryKeyPairName == "" && 49 c.Comm.SSHPrivateKey == "" && c.Comm.SSHPassword == "" { 50 51 c.TemporaryKeyPairName = fmt.Sprintf("packer_%s", uuid.TimeOrderedUUID()) 52 } 53 54 if c.UseFloatingIp && c.FloatingIpPool == "" { 55 c.FloatingIpPool = "public" 56 } 57 58 // Validation 59 errs := c.Comm.Prepare(ctx) 60 61 if c.SSHKeyPairName != "" { 62 if c.Comm.Type == "winrm" && c.Comm.WinRMPassword == "" && c.Comm.SSHPrivateKey == "" { 63 errs = append(errs, errors.New("A ssh_private_key_file must be provided to retrieve the winrm password when using ssh_keypair_name.")) 64 } else if c.Comm.SSHPrivateKey == "" && !c.Comm.SSHAgentAuth { 65 errs = append(errs, errors.New("A ssh_private_key_file must be provided or ssh_agent_auth enabled when ssh_keypair_name is specified.")) 66 } 67 } 68 69 if c.SourceImage == "" && c.SourceImageName == "" { 70 errs = append(errs, errors.New("Either a source_image or a source_image_name must be specified")) 71 } else if len(c.SourceImage) > 0 && len(c.SourceImageName) > 0 { 72 errs = append(errs, errors.New("Only a source_image or a source_image_name can be specified, not both.")) 73 } 74 75 if c.Flavor == "" { 76 errs = append(errs, errors.New("A flavor must be specified")) 77 } 78 79 if c.SSHIPVersion != "" && c.SSHIPVersion != "4" && c.SSHIPVersion != "6" { 80 errs = append(errs, errors.New("SSH IP version must be either 4 or 6")) 81 } 82 83 for key, value := range c.InstanceMetadata { 84 if len(key) > 255 { 85 errs = append(errs, fmt.Errorf("Instance metadata key too long (max 255 bytes): %s", key)) 86 } 87 if len(value) > 255 { 88 errs = append(errs, fmt.Errorf("Instance metadata value too long (max 255 bytes): %s", value)) 89 } 90 } 91 92 return errs 93 }