2019-05-31 08:27:41 -04:00
//go:generate struct-markdown
2019-10-14 10:43:59 -04:00
//go:generate mapstructure-to-hcl2 -type Config
2019-05-31 08:27:41 -04:00
2017-04-06 05:19:17 -04:00
package scaleway
import (
"errors"
"fmt"
2018-11-09 11:47:22 -05:00
"log"
2017-04-06 10:37:06 -04:00
"os"
2017-04-06 05:19:17 -04:00
2020-11-09 20:09:32 -05:00
"github.com/hashicorp/packer/builder/scaleway/version"
2017-04-06 05:19:17 -04:00
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/config"
2018-04-04 22:24:21 -04:00
"github.com/hashicorp/packer/helper/useragent"
2017-04-06 05:19:17 -04:00
"github.com/hashicorp/packer/packer"
2020-11-12 17:44:02 -05:00
"github.com/hashicorp/packer/packer-plugin-sdk/common"
2020-11-11 13:21:37 -05:00
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
2020-11-12 17:44:02 -05:00
"github.com/hashicorp/packer/packer-plugin-sdk/uuid"
2017-04-06 05:19:17 -04:00
"github.com/mitchellh/mapstructure"
2020-09-09 04:27:48 -04:00
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
2017-04-06 05:19:17 -04:00
)
type Config struct {
common . PackerConfig ` mapstructure:",squash" `
Comm communicator . Config ` mapstructure:",squash" `
2020-09-09 04:27:48 -04:00
// The AccessKey corresponding to the secret key.
// It can also be specified via the environment variable SCW_ACCESS_KEY.
AccessKey string ` mapstructure:"access_key" required:"true" `
// The SecretKey to authenticate against the Scaleway API.
// It can also be specified via the environment variable SCW_SECRET_KEY.
SecretKey string ` mapstructure:"secret_key" required:"true" `
// The Project ID in which the instances, volumes and snapshots will be created.
// It can also be specified via the environment variable SCW_DEFAULT_PROJECT_ID.
ProjectID string ` mapstructure:"project_id" required:"true" `
// The Zone in which the instances, volumes and snapshots will be created.
// It can also be specified via the environment variable SCW_DEFAULT_ZONE
Zone string ` mapstructure:"zone" required:"true" `
// The Scaleway API URL to use
// It can also be specified via the environment variable SCW_API_URL
APIURL string ` mapstructure:"api_url" `
2019-05-28 11:50:58 -04:00
// The UUID of the base image to use. This is the image
2019-06-06 10:29:25 -04:00
// that will be used to launch a new server and provision it. See
// the images list
// get the complete list of the accepted image UUID.
2020-10-07 10:04:00 -04:00
// The marketplace image label (eg `ubuntu_focal`) also works.
2019-06-06 10:29:25 -04:00
Image string ` mapstructure:"image" required:"true" `
2019-05-28 11:50:58 -04:00
// The name of the server commercial type:
2020-10-07 06:02:08 -04:00
// C1, C2L, C2M, C2S, DEV1-S, DEV1-M, DEV1-L, DEV1-XL,
// GP1-XS, GP1-S, GP1-M, GP1-L, GP1-XL, RENDER-S
2019-05-28 11:50:58 -04:00
CommercialType string ` mapstructure:"commercial_type" required:"true" `
// The name of the resulting snapshot that will
2019-06-06 10:29:25 -04:00
// appear in your account. Default packer-TIMESTAMP
2019-05-28 11:50:58 -04:00
SnapshotName string ` mapstructure:"snapshot_name" required:"false" `
// The name of the resulting image that will appear in
2019-06-06 10:29:25 -04:00
// your account. Default packer-TIMESTAMP
ImageName string ` mapstructure:"image_name" required:"false" `
2019-05-28 11:50:58 -04:00
// The name assigned to the server. Default
2019-06-06 10:29:25 -04:00
// packer-UUID
ServerName string ` mapstructure:"server_name" required:"false" `
2019-05-28 11:50:58 -04:00
// The id of an existing bootscript to use when
2019-06-06 10:29:25 -04:00
// booting the server.
Bootscript string ` mapstructure:"bootscript" required:"false" `
2019-05-28 11:50:58 -04:00
// The type of boot, can be either local or
2019-06-06 10:29:25 -04:00
// bootscript, Default bootscript
BootType string ` mapstructure:"boottype" required:"false" `
2017-04-06 05:19:17 -04:00
2019-07-18 16:42:18 -04:00
RemoveVolume bool ` mapstructure:"remove_volume" `
2020-07-31 11:22:55 -04:00
UserAgent string ` mapstructure-to-hcl2:",skip" `
2017-04-06 05:19:17 -04:00
ctx interpolate . Context
2020-09-09 04:27:48 -04:00
// Deprecated configs
// The token to use to authenticate with your account.
// It can also be specified via environment variable SCALEWAY_API_TOKEN. You
// can see and generate tokens in the "Credentials"
// section of the control panel.
// Deprecated, use SecretKey instead
Token string ` mapstructure:"api_token" required:"false" `
// The organization id to use to identify your
// organization. It can also be specified via environment variable
// SCALEWAY_ORGANIZATION. Your organization id is available in the
// "Account" section of the
// control panel.
// Previously named: api_access_key with environment variable: SCALEWAY_API_ACCESS_KEY
// Deprecated, use ProjectID instead
Organization string ` mapstructure:"organization_id" required:"false" `
// The name of the region to launch the server in (par1
// or ams1). Consequently, this is the region where the snapshot will be
// available.
// Deprecated, use Zone instead
Region string ` mapstructure:"region" required:"false" `
2017-04-06 05:19:17 -04:00
}
2019-12-17 05:25:56 -05:00
func ( c * Config ) Prepare ( raws ... interface { } ) ( [ ] string , error ) {
2017-04-06 05:19:17 -04:00
var md mapstructure . Metadata
err := config . Decode ( c , & config . DecodeOpts {
Metadata : & md ,
2020-10-21 19:07:18 -04:00
PluginType : BuilderId ,
2017-04-06 05:19:17 -04:00
Interpolate : true ,
InterpolateContext : & c . ctx ,
InterpolateFilter : & interpolate . RenderFilter {
Exclude : [ ] string {
"run_command" ,
} ,
} ,
} , raws ... )
if err != nil {
2019-12-17 05:25:56 -05:00
return nil , err
2017-04-06 05:19:17 -04:00
}
2020-09-09 04:27:48 -04:00
var warnings [ ] string
2020-11-09 20:09:32 -05:00
c . UserAgent = useragent . String ( version . ScalewayPluginVersion . FormattedVersion ( ) )
2017-04-06 05:19:17 -04:00
2020-09-09 04:27:48 -04:00
// Deprecated variables
2017-04-06 10:37:06 -04:00
if c . Organization == "" {
2018-11-09 11:47:22 -05:00
if os . Getenv ( "SCALEWAY_ORGANIZATION" ) != "" {
c . Organization = os . Getenv ( "SCALEWAY_ORGANIZATION" )
} else {
log . Printf ( "Deprecation warning: Use SCALEWAY_ORGANIZATION environment variable and organization_id argument instead of api_access_key argument and SCALEWAY_API_ACCESS_KEY environment variable." )
c . Organization = os . Getenv ( "SCALEWAY_API_ACCESS_KEY" )
}
2017-04-06 10:37:06 -04:00
}
2020-09-09 04:27:48 -04:00
if c . Organization != "" {
warnings = append ( warnings , "organization_id is deprecated in favor of project_id" )
c . ProjectID = c . Organization
}
2017-04-06 10:37:06 -04:00
if c . Token == "" {
c . Token = os . Getenv ( "SCALEWAY_API_TOKEN" )
}
2020-09-09 04:27:48 -04:00
if c . Token != "" {
warnings = append ( warnings , "token is deprecated in favor of secret_key" )
c . SecretKey = c . Token
}
if c . Region != "" {
warnings = append ( warnings , "region is deprecated in favor of zone" )
c . Zone = c . Region
}
if c . AccessKey == "" {
c . AccessKey = os . Getenv ( scw . ScwAccessKeyEnv )
}
if c . SecretKey == "" {
c . SecretKey = os . Getenv ( scw . ScwSecretKeyEnv )
}
if c . ProjectID == "" {
c . ProjectID = os . Getenv ( scw . ScwDefaultProjectIDEnv )
}
if c . Zone == "" {
c . Zone = os . Getenv ( scw . ScwDefaultZoneEnv )
}
if c . APIURL == "" {
c . APIURL = os . Getenv ( scw . ScwAPIURLEnv )
}
2017-04-06 10:37:06 -04:00
2017-04-06 05:19:17 -04:00
if c . SnapshotName == "" {
2017-04-11 06:19:28 -04:00
def , err := interpolate . Render ( "snapshot-packer-{{timestamp}}" , nil )
2017-04-06 05:19:17 -04:00
if err != nil {
panic ( err )
}
c . SnapshotName = def
}
2017-04-11 06:19:28 -04:00
if c . ImageName == "" {
def , err := interpolate . Render ( "image-packer-{{timestamp}}" , nil )
if err != nil {
panic ( err )
}
c . ImageName = def
}
2017-04-06 05:19:17 -04:00
if c . ServerName == "" {
// Default to packer-[time-ordered-uuid]
c . ServerName = fmt . Sprintf ( "packer-%s" , uuid . TimeOrderedUUID ( ) )
}
2018-09-27 10:27:33 -04:00
if c . BootType == "" {
2020-09-09 04:27:48 -04:00
c . BootType = instance . BootTypeLocal . String ( )
2018-09-27 10:27:33 -04:00
}
2017-04-06 05:19:17 -04:00
var errs * packer . MultiError
if es := c . Comm . Prepare ( & c . ctx ) ; len ( es ) > 0 {
errs = packer . MultiErrorAppend ( errs , es ... )
}
2020-09-09 04:27:48 -04:00
if c . ProjectID == "" {
2017-04-06 05:19:17 -04:00
errs = packer . MultiErrorAppend (
2020-09-09 04:27:48 -04:00
errs , errors . New ( "Scaleway Project ID must be specified" ) )
2017-04-06 05:19:17 -04:00
}
2020-09-09 04:27:48 -04:00
if c . SecretKey == "" {
2017-04-06 05:19:17 -04:00
errs = packer . MultiErrorAppend (
2020-09-09 04:27:48 -04:00
errs , errors . New ( "Scaleway Secret Key must be specified" ) )
}
if c . AccessKey == "" {
warnings = append ( warnings , "access_key will be required in future versions" )
c . AccessKey = "SCWXXXXXXXXXXXXXXXXX"
2017-04-06 05:19:17 -04:00
}
2020-09-09 04:27:48 -04:00
if c . Zone == "" {
2017-04-06 05:19:17 -04:00
errs = packer . MultiErrorAppend (
2020-09-09 04:27:48 -04:00
errs , errors . New ( "Scaleway Zone is required" ) )
2017-04-06 05:19:17 -04:00
}
if c . CommercialType == "" {
errs = packer . MultiErrorAppend (
errs , errors . New ( "commercial type is required" ) )
}
if c . Image == "" {
errs = packer . MultiErrorAppend (
errs , errors . New ( "image is required" ) )
}
if errs != nil && len ( errs . Errors ) > 0 {
2020-09-09 04:27:48 -04:00
return warnings , errs
2017-04-06 05:19:17 -04:00
}
2018-08-10 17:25:14 -04:00
packer . LogSecretFilter . Set ( c . Token )
2020-09-09 04:27:48 -04:00
return warnings , nil
2017-04-06 05:19:17 -04:00
}