github.phpd.cn/hashicorp/packer@v1.3.2/builder/hcloud/config.go (about) 1 package hcloud 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "time" 8 9 "github.com/hashicorp/packer/common" 10 "github.com/hashicorp/packer/common/uuid" 11 "github.com/hashicorp/packer/helper/communicator" 12 "github.com/hashicorp/packer/helper/config" 13 "github.com/hashicorp/packer/helper/multistep" 14 "github.com/hashicorp/packer/packer" 15 "github.com/hashicorp/packer/template/interpolate" 16 "github.com/hetznercloud/hcloud-go/hcloud" 17 "github.com/mitchellh/mapstructure" 18 ) 19 20 type Config struct { 21 common.PackerConfig `mapstructure:",squash"` 22 Comm communicator.Config `mapstructure:",squash"` 23 24 HCloudToken string `mapstructure:"token"` 25 Endpoint string `mapstructure:"endpoint"` 26 PollInterval time.Duration `mapstructure:"poll_interval"` 27 28 ServerName string `mapstructure:"server_name"` 29 Location string `mapstructure:"location"` 30 ServerType string `mapstructure:"server_type"` 31 Image string `mapstructure:"image"` 32 33 SnapshotName string `mapstructure:"snapshot_name"` 34 UserData string `mapstructure:"user_data"` 35 UserDataFile string `mapstructure:"user_data_file"` 36 37 ctx interpolate.Context 38 } 39 40 func NewConfig(raws ...interface{}) (*Config, []string, error) { 41 c := new(Config) 42 43 var md mapstructure.Metadata 44 err := config.Decode(c, &config.DecodeOpts{ 45 Metadata: &md, 46 Interpolate: true, 47 InterpolateContext: &c.ctx, 48 InterpolateFilter: &interpolate.RenderFilter{ 49 Exclude: []string{ 50 "run_command", 51 }, 52 }, 53 }, raws...) 54 if err != nil { 55 return nil, nil, err 56 } 57 58 // Defaults 59 if c.HCloudToken == "" { 60 c.HCloudToken = os.Getenv("HCLOUD_TOKEN") 61 } 62 if c.Endpoint == "" { 63 if os.Getenv("HCLOUD_ENDPOINT") != "" { 64 c.Endpoint = os.Getenv("HCLOUD_ENDPOINT") 65 } else { 66 c.Endpoint = hcloud.Endpoint 67 } 68 } 69 if c.PollInterval == 0 { 70 c.PollInterval = 500 * time.Millisecond 71 } 72 73 if c.SnapshotName == "" { 74 def, err := interpolate.Render("packer-{{timestamp}}", nil) 75 if err != nil { 76 panic(err) 77 } 78 // Default to packer-{{ unix timestamp (utc) }} 79 c.SnapshotName = def 80 } 81 82 if c.ServerName == "" { 83 // Default to packer-[time-ordered-uuid] 84 c.ServerName = fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()) 85 } 86 87 var errs *packer.MultiError 88 if es := c.Comm.Prepare(&c.ctx); len(es) > 0 { 89 errs = packer.MultiErrorAppend(errs, es...) 90 } 91 if c.HCloudToken == "" { 92 // Required configurations that will display errors if not set 93 errs = packer.MultiErrorAppend( 94 errs, errors.New("token for auth must be specified")) 95 } 96 97 if c.Location == "" { 98 errs = packer.MultiErrorAppend( 99 errs, errors.New("location is required")) 100 } 101 102 if c.ServerType == "" { 103 errs = packer.MultiErrorAppend( 104 errs, errors.New("server type is required")) 105 } 106 107 if c.Image == "" { 108 errs = packer.MultiErrorAppend( 109 errs, errors.New("image is required")) 110 } 111 112 if c.UserData != "" && c.UserDataFile != "" { 113 errs = packer.MultiErrorAppend( 114 errs, errors.New("only one of user_data or user_data_file can be specified")) 115 } else if c.UserDataFile != "" { 116 if _, err := os.Stat(c.UserDataFile); err != nil { 117 errs = packer.MultiErrorAppend( 118 errs, errors.New(fmt.Sprintf("user_data_file not found: %s", c.UserDataFile))) 119 } 120 } 121 122 if errs != nil && len(errs.Errors) > 0 { 123 return nil, nil, errs 124 } 125 126 packer.LogSecretFilter.Set(c.HCloudToken) 127 return c, nil, nil 128 } 129 130 func getServerIP(state multistep.StateBag) (string, error) { 131 return state.Get("server_ip").(string), nil 132 }