github.com/rothwerx/packer@v0.9.0/builder/digitalocean/config.go (about) 1 package digitalocean 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "time" 8 9 "github.com/mitchellh/mapstructure" 10 "github.com/mitchellh/packer/common" 11 "github.com/mitchellh/packer/common/uuid" 12 "github.com/mitchellh/packer/helper/communicator" 13 "github.com/mitchellh/packer/helper/config" 14 "github.com/mitchellh/packer/packer" 15 "github.com/mitchellh/packer/template/interpolate" 16 ) 17 18 type Config struct { 19 common.PackerConfig `mapstructure:",squash"` 20 Comm communicator.Config `mapstructure:",squash"` 21 22 APIToken string `mapstructure:"api_token"` 23 APIURL string `mapstructure:"api_url"` 24 25 Region string `mapstructure:"region"` 26 Size string `mapstructure:"size"` 27 Image string `mapstructure:"image"` 28 29 PrivateNetworking bool `mapstructure:"private_networking"` 30 SnapshotName string `mapstructure:"snapshot_name"` 31 StateTimeout time.Duration `mapstructure:"state_timeout"` 32 DropletName string `mapstructure:"droplet_name"` 33 UserData string `mapstructure:"user_data"` 34 35 ctx interpolate.Context 36 } 37 38 func NewConfig(raws ...interface{}) (*Config, []string, error) { 39 c := new(Config) 40 41 var md mapstructure.Metadata 42 err := config.Decode(c, &config.DecodeOpts{ 43 Metadata: &md, 44 Interpolate: true, 45 InterpolateContext: &c.ctx, 46 InterpolateFilter: &interpolate.RenderFilter{ 47 Exclude: []string{ 48 "run_command", 49 }, 50 }, 51 }, raws...) 52 if err != nil { 53 return nil, nil, err 54 } 55 56 // Defaults 57 if c.APIToken == "" { 58 // Default to environment variable for api_token, if it exists 59 c.APIToken = os.Getenv("DIGITALOCEAN_API_TOKEN") 60 } 61 if c.APIURL == "" { 62 c.APIURL = os.Getenv("DIGITALOCEAN_API_URL") 63 } 64 if c.SnapshotName == "" { 65 def, err := interpolate.Render("packer-{{timestamp}}", nil) 66 if err != nil { 67 panic(err) 68 } 69 70 // Default to packer-{{ unix timestamp (utc) }} 71 c.SnapshotName = def 72 } 73 74 if c.DropletName == "" { 75 // Default to packer-[time-ordered-uuid] 76 c.DropletName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()) 77 } 78 79 if c.Comm.SSHUsername == "" { 80 // Default to "root". You can override this if your 81 // SourceImage has a different user account then the DO default 82 c.Comm.SSHUsername = "root" 83 } 84 85 if c.StateTimeout == 0 { 86 // Default to 6 minute timeouts waiting for 87 // desired state. i.e waiting for droplet to become active 88 c.StateTimeout = 6 * time.Minute 89 } 90 91 var errs *packer.MultiError 92 if es := c.Comm.Prepare(&c.ctx); len(es) > 0 { 93 errs = packer.MultiErrorAppend(errs, es...) 94 } 95 if c.APIToken == "" { 96 // Required configurations that will display errors if not set 97 errs = packer.MultiErrorAppend( 98 errs, errors.New("api_token for auth must be specified")) 99 } 100 101 if c.Region == "" { 102 errs = packer.MultiErrorAppend( 103 errs, errors.New("region is required")) 104 } 105 106 if c.Size == "" { 107 errs = packer.MultiErrorAppend( 108 errs, errors.New("size is required")) 109 } 110 111 if c.Image == "" { 112 errs = packer.MultiErrorAppend( 113 errs, errors.New("image is required")) 114 } 115 116 if errs != nil && len(errs.Errors) > 0 { 117 return nil, nil, errs 118 } 119 120 common.ScrubConfig(c, c.APIToken) 121 return c, nil, nil 122 }