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  }