github.com/emate/packer@v0.8.1-0.20150625195101-fe0fde195dc6/helper/communicator/config.go (about) 1 package communicator 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "time" 8 9 "github.com/mitchellh/packer/template/interpolate" 10 ) 11 12 // Config is the common configuration that communicators allow within 13 // a builder. 14 type Config struct { 15 Type string `mapstructure:"communicator"` 16 17 // SSH 18 SSHHost string `mapstructure:"ssh_host"` 19 SSHPort int `mapstructure:"ssh_port"` 20 SSHUsername string `mapstructure:"ssh_username"` 21 SSHPassword string `mapstructure:"ssh_password"` 22 SSHPrivateKey string `mapstructure:"ssh_private_key_file"` 23 SSHPty bool `mapstructure:"ssh_pty"` 24 SSHTimeout time.Duration `mapstructure:"ssh_timeout"` 25 SSHDisableAgent bool `mapstructure:"ssh_disable_agent"` 26 SSHHandshakeAttempts int `mapstructure:"ssh_handshake_attempts"` 27 SSHBastionHost string `mapstructure:"ssh_bastion_host"` 28 SSHBastionPort int `mapstructure:"ssh_bastion_port"` 29 SSHBastionUsername string `mapstructure:"ssh_bastion_username"` 30 SSHBastionPassword string `mapstructure:"ssh_bastion_password"` 31 SSHBastionPrivateKey string `mapstructure:"ssh_bastion_private_key_file"` 32 33 // WinRM 34 WinRMUser string `mapstructure:"winrm_username"` 35 WinRMPassword string `mapstructure:"winrm_password"` 36 WinRMHost string `mapstructure:"winrm_host"` 37 WinRMPort int `mapstructure:"winrm_port"` 38 WinRMTimeout time.Duration `mapstructure:"winrm_timeout"` 39 } 40 41 // Port returns the port that will be used for access based on config. 42 func (c *Config) Port() int { 43 switch c.Type { 44 case "ssh": 45 return c.SSHPort 46 case "winrm": 47 return c.WinRMPort 48 default: 49 return 0 50 } 51 } 52 53 func (c *Config) Prepare(ctx *interpolate.Context) []error { 54 if c.Type == "" { 55 c.Type = "ssh" 56 } 57 58 var errs []error 59 switch c.Type { 60 case "ssh": 61 if es := c.prepareSSH(ctx); len(es) > 0 { 62 errs = append(errs, es...) 63 } 64 case "winrm": 65 if es := c.prepareWinRM(ctx); len(es) > 0 { 66 errs = append(errs, es...) 67 } 68 } 69 70 return errs 71 } 72 73 func (c *Config) prepareSSH(ctx *interpolate.Context) []error { 74 if c.SSHPort == 0 { 75 c.SSHPort = 22 76 } 77 78 if c.SSHTimeout == 0 { 79 c.SSHTimeout = 5 * time.Minute 80 } 81 82 if c.SSHHandshakeAttempts == 0 { 83 c.SSHHandshakeAttempts = 10 84 } 85 86 if c.SSHBastionHost != "" { 87 if c.SSHBastionPort == 0 { 88 c.SSHBastionPort = 22 89 } 90 91 if c.SSHBastionPrivateKey == "" && c.SSHPrivateKey != "" { 92 c.SSHBastionPrivateKey = c.SSHPrivateKey 93 } 94 } 95 96 // Validation 97 var errs []error 98 if c.SSHUsername == "" { 99 errs = append(errs, errors.New("An ssh_username must be specified")) 100 } 101 102 if c.SSHPrivateKey != "" { 103 if _, err := os.Stat(c.SSHPrivateKey); err != nil { 104 errs = append(errs, fmt.Errorf( 105 "ssh_private_key_file is invalid: %s", err)) 106 } else if _, err := SSHFileSigner(c.SSHPrivateKey); err != nil { 107 errs = append(errs, fmt.Errorf( 108 "ssh_private_key_file is invalid: %s", err)) 109 } 110 } 111 112 if c.SSHBastionHost != "" { 113 if c.SSHBastionPassword == "" && c.SSHBastionPrivateKey == "" { 114 errs = append(errs, errors.New( 115 "ssh_bastion_password or ssh_bastion_private_key_file must be specified")) 116 } 117 } 118 119 return errs 120 } 121 122 func (c *Config) prepareWinRM(ctx *interpolate.Context) []error { 123 if c.WinRMPort == 0 { 124 c.WinRMPort = 5985 125 } 126 127 if c.WinRMTimeout == 0 { 128 c.WinRMTimeout = 30 * time.Minute 129 } 130 131 var errs []error 132 if c.WinRMUser == "" { 133 errs = append(errs, errors.New("winrm_username must be specified.")) 134 } 135 136 return errs 137 }