yandex-import: allow set custom API endpoint (#9850)

* Separate Access Config from yandex builder Config

* make use of Access Config explicit

* Move `MaxRetries` into AccessConfig

* NewDriverYC use AccessConfig instead Config

* yandex-import PP use common Access Config

Now support set custom API Endpoint

* yandex-export PP use common Access Config

Now support set custom API Endpoint too (as yandex-import)

* fix test

* Tiny doc updates.
This commit is contained in:
GennadySpb 2020-08-31 16:29:20 +03:00 committed by GitHub
parent f578b93f7e
commit 804fefef17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 178 additions and 194 deletions

View File

@ -0,0 +1,67 @@
//go:generate struct-markdown
package yandex
import (
"errors"
"fmt"
"os"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate"
"github.com/yandex-cloud/go-sdk/iamkey"
)
const defaultEndpoint = "api.cloud.yandex.net:443"
// AccessConfig is for common configuration related to Yandex.Cloud API access
type AccessConfig struct {
// Non standard API endpoint. Default is `api.cloud.yandex.net:443`.
Endpoint string `mapstructure:"endpoint" required:"false"`
// Path to file with Service Account key in json format. This
// is an alternative method to authenticate to Yandex.Cloud. Alternatively you may set environment variable
// `YC_SERVICE_ACCOUNT_KEY_FILE`.
ServiceAccountKeyFile string `mapstructure:"service_account_key_file" required:"false"`
// OAuth token to use to authenticate to Yandex.Cloud. Alternatively you may set
// value by environment variable `YC_TOKEN`.
Token string `mapstructure:"token" required:"true"`
// The maximum number of times an API request is being executed.
MaxRetries int `mapstructure:"max_retries"`
}
func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
var errs []error
if c.Endpoint == "" {
c.Endpoint = defaultEndpoint
}
// provision config by OS environment variables
if c.Token == "" {
c.Token = os.Getenv("YC_TOKEN")
}
if c.ServiceAccountKeyFile == "" {
c.ServiceAccountKeyFile = os.Getenv("YC_SERVICE_ACCOUNT_KEY_FILE")
}
if c.Token != "" && c.ServiceAccountKeyFile != "" {
errs = append(errs, errors.New("one of token or service account key file must be specified, not both"))
}
if c.Token != "" {
packer.LogSecretFilter.Set(c.Token)
}
if c.ServiceAccountKeyFile != "" {
if _, err := iamkey.ReadFromJSONFile(c.ServiceAccountKeyFile); err != nil {
errs = append(errs, fmt.Errorf("fail to read service account key file: %s", err))
}
}
if len(errs) > 0 {
return errs
}
return nil
}

View File

@ -50,7 +50,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
// Run executes a yandex Packer build and returns a packer.Artifact // Run executes a yandex Packer build and returns a packer.Artifact
// representing a Yandex.Cloud compute image. // representing a Yandex.Cloud compute image.
func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) { func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
driver, err := NewDriverYC(ui, &b.config) driver, err := NewDriverYC(ui, &b.config.AccessConfig)
ctx = requestid.ContextWithClientTraceID(ctx, uuid.New().String()) ctx = requestid.ContextWithClientTraceID(ctx, uuid.New().String())
if err != nil { if err != nil {

View File

@ -16,11 +16,8 @@ import (
"github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate" "github.com/hashicorp/packer/template/interpolate"
"github.com/yandex-cloud/go-sdk/iamkey"
) )
const defaultEndpoint = "api.cloud.yandex.net:443"
const defaultGpuPlatformID = "gpu-standard-v1" const defaultGpuPlatformID = "gpu-standard-v1"
const defaultPlatformID = "standard-v1" const defaultPlatformID = "standard-v1"
const defaultMaxRetries = 3 const defaultMaxRetries = 3
@ -31,23 +28,15 @@ var reImageFamily = regexp.MustCompile(`^[a-z]([-a-z0-9]{0,61}[a-z0-9])?$`)
type Config struct { type Config struct {
common.PackerConfig `mapstructure:",squash"` common.PackerConfig `mapstructure:",squash"`
Communicator communicator.Config `mapstructure:",squash"` Communicator communicator.Config `mapstructure:",squash"`
AccessConfig `mapstructure:",squash"`
// Non standard api endpoint URL.
Endpoint string `mapstructure:"endpoint" required:"false"`
// The folder ID that will be used to launch instances and store images. // The folder ID that will be used to launch instances and store images.
// Alternatively you may set value by environment variable YC_FOLDER_ID. // Alternatively you may set value by environment variable `YC_FOLDER_ID`.
// To use a different folder for looking up the source image or saving the target image to // To use a different folder for looking up the source image or saving the target image to
// check options 'source_image_folder_id' and 'target_image_folder_id'. // check options 'source_image_folder_id' and 'target_image_folder_id'.
FolderID string `mapstructure:"folder_id" required:"true"` FolderID string `mapstructure:"folder_id" required:"true"`
// Path to file with Service Account key in json format. This // Service account identifier to assign to instance.
// is an alternative method to authenticate to Yandex.Cloud. Alternatively you may set environment variable
// YC_SERVICE_ACCOUNT_KEY_FILE.
ServiceAccountKeyFile string `mapstructure:"service_account_key_file" required:"false"`
// Service account identifier to assign to instance
ServiceAccountID string `mapstructure:"service_account_id" required:"false"` ServiceAccountID string `mapstructure:"service_account_id" required:"false"`
// OAuth token to use to authenticate to Yandex.Cloud. Alternatively you may set
// value by environment variable YC_TOKEN.
Token string `mapstructure:"token" required:"true"`
// The name of the disk, if unset the instance name // The name of the disk, if unset the instance name
// will be used. // will be used.
DiskName string `mapstructure:"disk_name" required:"false"` DiskName string `mapstructure:"disk_name" required:"false"`
@ -59,8 +48,7 @@ type Config struct {
ImageDescription string `mapstructure:"image_description" required:"false"` ImageDescription string `mapstructure:"image_description" required:"false"`
// The family name of the resulting image. // The family name of the resulting image.
ImageFamily string `mapstructure:"image_family" required:"false"` ImageFamily string `mapstructure:"image_family" required:"false"`
// Key/value pair labels to // Key/value pair labels to apply to the created image.
// apply to the created image.
ImageLabels map[string]string `mapstructure:"image_labels" required:"false"` ImageLabels map[string]string `mapstructure:"image_labels" required:"false"`
// Minimum size of the disk that will be created from built image, specified in gigabytes. // Minimum size of the disk that will be created from built image, specified in gigabytes.
// Should be more or equal to `disk_size_gb`. // Should be more or equal to `disk_size_gb`.
@ -78,16 +66,14 @@ type Config struct {
InstanceMemory int `mapstructure:"instance_mem_gb" required:"false"` InstanceMemory int `mapstructure:"instance_mem_gb" required:"false"`
// The name assigned to the instance. // The name assigned to the instance.
InstanceName string `mapstructure:"instance_name" required:"false"` InstanceName string `mapstructure:"instance_name" required:"false"`
// Key/value pair labels to apply to // Key/value pair labels to apply to the launched instance.
// the launched instance.
Labels map[string]string `mapstructure:"labels" required:"false"` Labels map[string]string `mapstructure:"labels" required:"false"`
// Identifier of the hardware platform configuration for the instance. This defaults to `standard-v1`. // Identifier of the hardware platform configuration for the instance. This defaults to `standard-v1`.
PlatformID string `mapstructure:"platform_id" required:"false"` PlatformID string `mapstructure:"platform_id" required:"false"`
// The maximum number of times an API request is being executed
MaxRetries int `mapstructure:"max_retries"`
// Metadata applied to the launched instance. // Metadata applied to the launched instance.
Metadata map[string]string `mapstructure:"metadata" required:"false"` Metadata map[string]string `mapstructure:"metadata" required:"false"`
// Metadata applied to the launched instance. Value are file paths. // Metadata applied to the launched instance.
// The values in this map are the paths to the content files for the corresponding metadata keys.
MetadataFromFile map[string]string `mapstructure:"metadata_from_file"` MetadataFromFile map[string]string `mapstructure:"metadata_from_file"`
// Launch a preemptible instance. This defaults to `false`. // Launch a preemptible instance. This defaults to `false`.
Preemptible bool `mapstructure:"preemptible"` Preemptible bool `mapstructure:"preemptible"`
@ -95,12 +81,11 @@ type Config struct {
SerialLogFile string `mapstructure:"serial_log_file" required:"false"` SerialLogFile string `mapstructure:"serial_log_file" required:"false"`
// The source image family to create the new image // The source image family to create the new image
// from. You can also specify source_image_id instead. Just one of a source_image_id or // from. You can also specify source_image_id instead. Just one of a source_image_id or
// source_image_family must be specified. Example: `ubuntu-1804-lts` // source_image_family must be specified. Example: `ubuntu-1804-lts`.
SourceImageFamily string `mapstructure:"source_image_family" required:"true"` SourceImageFamily string `mapstructure:"source_image_family" required:"true"`
// The ID of the folder containing the source image. // The ID of the folder containing the source image.
SourceImageFolderID string `mapstructure:"source_image_folder_id" required:"false"` SourceImageFolderID string `mapstructure:"source_image_folder_id" required:"false"`
// The source image ID to use to create the new image // The source image ID to use to create the new image from.
// from.
SourceImageID string `mapstructure:"source_image_id" required:"false"` SourceImageID string `mapstructure:"source_image_id" required:"false"`
// The source image name to use to create the new image // The source image name to use to create the new image
// from. Name will be looked up in `source_image_folder_id`. // from. Name will be looked up in `source_image_folder_id`.
@ -142,8 +127,11 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
return nil, err return nil, err
} }
// Accumulate any errors
var errs *packer.MultiError var errs *packer.MultiError
errs = packer.MultiErrorAppend(errs, c.AccessConfig.Prepare(&c.ctx)...)
if c.SerialLogFile != "" { if c.SerialLogFile != "" {
if _, err := os.Stat(c.SerialLogFile); os.IsExist(err) { if _, err := os.Stat(c.SerialLogFile); os.IsExist(err) {
errs = packer.MultiErrorAppend(errs, errs = packer.MultiErrorAppend(errs,
@ -236,10 +224,6 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
} }
} }
if c.Endpoint == "" {
c.Endpoint = defaultEndpoint
}
if c.Zone == "" { if c.Zone == "" {
c.Zone = defaultZone c.Zone = defaultZone
} }
@ -248,35 +232,10 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
c.MaxRetries = defaultMaxRetries c.MaxRetries = defaultMaxRetries
} }
// provision config by OS environment variables
if c.Token == "" {
c.Token = os.Getenv("YC_TOKEN")
}
if c.ServiceAccountKeyFile == "" {
c.ServiceAccountKeyFile = os.Getenv("YC_SERVICE_ACCOUNT_KEY_FILE")
}
if c.FolderID == "" { if c.FolderID == "" {
c.FolderID = os.Getenv("YC_FOLDER_ID") c.FolderID = os.Getenv("YC_FOLDER_ID")
} }
if c.Token != "" && c.ServiceAccountKeyFile != "" {
errs = packer.MultiErrorAppend(
errs, errors.New("one of token or service account key file must be specified, not both"))
}
if c.Token != "" {
packer.LogSecretFilter.Set(c.Token)
}
if c.ServiceAccountKeyFile != "" {
if _, err := iamkey.ReadFromJSONFile(c.ServiceAccountKeyFile); err != nil {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("fail to read service account key file: %s", err))
}
}
if c.FolderID == "" { if c.FolderID == "" {
errs = packer.MultiErrorAppend( errs = packer.MultiErrorAppend(
errs, errors.New("a folder_id must be specified")) errs, errors.New("a folder_id must be specified"))

View File

@ -64,10 +64,11 @@ type FlatConfig struct {
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure" hcl:"winrm_insecure"` WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure" hcl:"winrm_insecure"`
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm" hcl:"winrm_use_ntlm"` WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm" hcl:"winrm_use_ntlm"`
Endpoint *string `mapstructure:"endpoint" required:"false" cty:"endpoint" hcl:"endpoint"` Endpoint *string `mapstructure:"endpoint" required:"false" cty:"endpoint" hcl:"endpoint"`
FolderID *string `mapstructure:"folder_id" required:"true" cty:"folder_id" hcl:"folder_id"`
ServiceAccountKeyFile *string `mapstructure:"service_account_key_file" required:"false" cty:"service_account_key_file" hcl:"service_account_key_file"` ServiceAccountKeyFile *string `mapstructure:"service_account_key_file" required:"false" cty:"service_account_key_file" hcl:"service_account_key_file"`
ServiceAccountID *string `mapstructure:"service_account_id" required:"false" cty:"service_account_id" hcl:"service_account_id"`
Token *string `mapstructure:"token" required:"true" cty:"token" hcl:"token"` Token *string `mapstructure:"token" required:"true" cty:"token" hcl:"token"`
MaxRetries *int `mapstructure:"max_retries" cty:"max_retries" hcl:"max_retries"`
FolderID *string `mapstructure:"folder_id" required:"true" cty:"folder_id" hcl:"folder_id"`
ServiceAccountID *string `mapstructure:"service_account_id" required:"false" cty:"service_account_id" hcl:"service_account_id"`
DiskName *string `mapstructure:"disk_name" required:"false" cty:"disk_name" hcl:"disk_name"` DiskName *string `mapstructure:"disk_name" required:"false" cty:"disk_name" hcl:"disk_name"`
DiskSizeGb *int `mapstructure:"disk_size_gb" required:"false" cty:"disk_size_gb" hcl:"disk_size_gb"` DiskSizeGb *int `mapstructure:"disk_size_gb" required:"false" cty:"disk_size_gb" hcl:"disk_size_gb"`
DiskType *string `mapstructure:"disk_type" required:"false" cty:"disk_type" hcl:"disk_type"` DiskType *string `mapstructure:"disk_type" required:"false" cty:"disk_type" hcl:"disk_type"`
@ -83,7 +84,6 @@ type FlatConfig struct {
InstanceName *string `mapstructure:"instance_name" required:"false" cty:"instance_name" hcl:"instance_name"` InstanceName *string `mapstructure:"instance_name" required:"false" cty:"instance_name" hcl:"instance_name"`
Labels map[string]string `mapstructure:"labels" required:"false" cty:"labels" hcl:"labels"` Labels map[string]string `mapstructure:"labels" required:"false" cty:"labels" hcl:"labels"`
PlatformID *string `mapstructure:"platform_id" required:"false" cty:"platform_id" hcl:"platform_id"` PlatformID *string `mapstructure:"platform_id" required:"false" cty:"platform_id" hcl:"platform_id"`
MaxRetries *int `mapstructure:"max_retries" cty:"max_retries" hcl:"max_retries"`
Metadata map[string]string `mapstructure:"metadata" required:"false" cty:"metadata" hcl:"metadata"` Metadata map[string]string `mapstructure:"metadata" required:"false" cty:"metadata" hcl:"metadata"`
MetadataFromFile map[string]string `mapstructure:"metadata_from_file" cty:"metadata_from_file" hcl:"metadata_from_file"` MetadataFromFile map[string]string `mapstructure:"metadata_from_file" cty:"metadata_from_file" hcl:"metadata_from_file"`
Preemptible *bool `mapstructure:"preemptible" cty:"preemptible" hcl:"preemptible"` Preemptible *bool `mapstructure:"preemptible" cty:"preemptible" hcl:"preemptible"`
@ -168,10 +168,11 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false}, "winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false},
"winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false}, "winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false},
"endpoint": &hcldec.AttrSpec{Name: "endpoint", Type: cty.String, Required: false}, "endpoint": &hcldec.AttrSpec{Name: "endpoint", Type: cty.String, Required: false},
"folder_id": &hcldec.AttrSpec{Name: "folder_id", Type: cty.String, Required: false},
"service_account_key_file": &hcldec.AttrSpec{Name: "service_account_key_file", Type: cty.String, Required: false}, "service_account_key_file": &hcldec.AttrSpec{Name: "service_account_key_file", Type: cty.String, Required: false},
"service_account_id": &hcldec.AttrSpec{Name: "service_account_id", Type: cty.String, Required: false},
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false}, "token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
"max_retries": &hcldec.AttrSpec{Name: "max_retries", Type: cty.Number, Required: false},
"folder_id": &hcldec.AttrSpec{Name: "folder_id", Type: cty.String, Required: false},
"service_account_id": &hcldec.AttrSpec{Name: "service_account_id", Type: cty.String, Required: false},
"disk_name": &hcldec.AttrSpec{Name: "disk_name", Type: cty.String, Required: false}, "disk_name": &hcldec.AttrSpec{Name: "disk_name", Type: cty.String, Required: false},
"disk_size_gb": &hcldec.AttrSpec{Name: "disk_size_gb", Type: cty.Number, Required: false}, "disk_size_gb": &hcldec.AttrSpec{Name: "disk_size_gb", Type: cty.Number, Required: false},
"disk_type": &hcldec.AttrSpec{Name: "disk_type", Type: cty.String, Required: false}, "disk_type": &hcldec.AttrSpec{Name: "disk_type", Type: cty.String, Required: false},
@ -187,7 +188,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"instance_name": &hcldec.AttrSpec{Name: "instance_name", Type: cty.String, Required: false}, "instance_name": &hcldec.AttrSpec{Name: "instance_name", Type: cty.String, Required: false},
"labels": &hcldec.AttrSpec{Name: "labels", Type: cty.Map(cty.String), Required: false}, "labels": &hcldec.AttrSpec{Name: "labels", Type: cty.Map(cty.String), Required: false},
"platform_id": &hcldec.AttrSpec{Name: "platform_id", Type: cty.String, Required: false}, "platform_id": &hcldec.AttrSpec{Name: "platform_id", Type: cty.String, Required: false},
"max_retries": &hcldec.AttrSpec{Name: "max_retries", Type: cty.Number, Required: false},
"metadata": &hcldec.AttrSpec{Name: "metadata", Type: cty.Map(cty.String), Required: false}, "metadata": &hcldec.AttrSpec{Name: "metadata", Type: cty.Map(cty.String), Required: false},
"metadata_from_file": &hcldec.AttrSpec{Name: "metadata_from_file", Type: cty.Map(cty.String), Required: false}, "metadata_from_file": &hcldec.AttrSpec{Name: "metadata_from_file", Type: cty.Map(cty.String), Required: false},
"preemptible": &hcldec.AttrSpec{Name: "preemptible", Type: cty.Bool, Required: false}, "preemptible": &hcldec.AttrSpec{Name: "preemptible", Type: cty.Bool, Required: false},

View File

@ -33,27 +33,27 @@ type driverYC struct {
ui packer.Ui ui packer.Ui
} }
func NewDriverYC(ui packer.Ui, config *Config) (Driver, error) { func NewDriverYC(ui packer.Ui, ac *AccessConfig) (Driver, error) {
log.Printf("[INFO] Initialize Yandex.Cloud client...") log.Printf("[INFO] Initialize Yandex.Cloud client...")
sdkConfig := ycsdk.Config{} sdkConfig := ycsdk.Config{}
if config.Endpoint != "" { if ac.Endpoint != "" {
sdkConfig.Endpoint = config.Endpoint sdkConfig.Endpoint = ac.Endpoint
} }
switch { switch {
case config.Token == "" && config.ServiceAccountKeyFile == "": case ac.Token == "" && ac.ServiceAccountKeyFile == "":
log.Printf("[INFO] Use Instance Service Account for authentication") log.Printf("[INFO] Use Instance Service Account for authentication")
sdkConfig.Credentials = ycsdk.InstanceServiceAccount() sdkConfig.Credentials = ycsdk.InstanceServiceAccount()
case config.Token != "": case ac.Token != "":
log.Printf("[INFO] Use OAuth token for authentication") log.Printf("[INFO] Use OAuth token for authentication")
sdkConfig.Credentials = ycsdk.OAuthToken(config.Token) sdkConfig.Credentials = ycsdk.OAuthToken(ac.Token)
case config.ServiceAccountKeyFile != "": case ac.ServiceAccountKeyFile != "":
log.Printf("[INFO] Use Service Account key file %q for authentication", config.ServiceAccountKeyFile) log.Printf("[INFO] Use Service Account key file %q for authentication", ac.ServiceAccountKeyFile)
key, err := iamkey.ReadFromJSONFile(config.ServiceAccountKeyFile) key, err := iamkey.ReadFromJSONFile(ac.ServiceAccountKeyFile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -69,7 +69,7 @@ func NewDriverYC(ui packer.Ui, config *Config) (Driver, error) {
requestIDInterceptor := requestid.Interceptor() requestIDInterceptor := requestid.Interceptor()
retryInterceptor := retry.Interceptor( retryInterceptor := retry.Interceptor(
retry.WithMax(config.MaxRetries), retry.WithMax(ac.MaxRetries),
retry.WithCodes(codes.Unavailable), retry.WithCodes(codes.Unavailable),
retry.WithAttemptHeader(true), retry.WithAttemptHeader(true),
retry.WithBackoff(retry.BackoffExponentialWithJitter(defaultExponentialBackoffBase, defaultExponentialBackoffCap))) retry.WithBackoff(retry.BackoffExponentialWithJitter(defaultExponentialBackoffBase, defaultExponentialBackoffCap)))

View File

@ -11,8 +11,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/yandex-cloud/go-sdk/iamkey"
"github.com/hashicorp/hcl/v2/hcldec" "github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer/builder" "github.com/hashicorp/packer/builder"
"github.com/hashicorp/packer/builder/yandex" "github.com/hashicorp/packer/builder/yandex"
@ -28,6 +26,7 @@ const defaultStorageEndpoint = "storage.yandexcloud.net"
type Config struct { type Config struct {
common.PackerConfig `mapstructure:",squash"` common.PackerConfig `mapstructure:",squash"`
yandex.AccessConfig `mapstructure:",squash"`
// List of paths to Yandex Object Storage where exported image will be uploaded. // List of paths to Yandex Object Storage where exported image will be uploaded.
// Please be aware that use of space char inside path not supported. // Please be aware that use of space char inside path not supported.
@ -36,7 +35,7 @@ type Config struct {
// Paths to Yandex Object Storage where exported image will be uploaded. // Paths to Yandex Object Storage where exported image will be uploaded.
Paths []string `mapstructure:"paths" required:"true"` Paths []string `mapstructure:"paths" required:"true"`
// The folder ID that will be used to launch a temporary instance. // The folder ID that will be used to launch a temporary instance.
// Alternatively you may set value by environment variable YC_FOLDER_ID. // Alternatively you may set value by environment variable `YC_FOLDER_ID`.
FolderID string `mapstructure:"folder_id" required:"true"` FolderID string `mapstructure:"folder_id" required:"true"`
// Service Account ID with proper permission to modify an instance, create and attach disk and // Service Account ID with proper permission to modify an instance, create and attach disk and
// make upload to specific Yandex Object Storage paths. // make upload to specific Yandex Object Storage paths.
@ -53,13 +52,6 @@ type Config struct {
SubnetID string `mapstructure:"subnet_id" required:"false"` SubnetID string `mapstructure:"subnet_id" required:"false"`
// The name of the zone to launch the instance. This defaults to `ru-central1-a`. // The name of the zone to launch the instance. This defaults to `ru-central1-a`.
Zone string `mapstructure:"zone" required:"false"` Zone string `mapstructure:"zone" required:"false"`
// OAuth token to use to authenticate to Yandex.Cloud. Alternatively you may set
// value by environment variable YC_TOKEN.
Token string `mapstructure:"token" required:"false"`
// Path to file with Service Account key in json format. This
// is an alternative method to authenticate to Yandex.Cloud. Alternatively you may set environment variable
// YC_SERVICE_ACCOUNT_KEY_FILE.
ServiceAccountKeyFile string `mapstructure:"service_account_key_file" required:"false"`
ctx interpolate.Context ctx interpolate.Context
} }
@ -85,7 +77,10 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
return err return err
} }
errs := new(packer.MultiError) // Accumulate any errors
var errs *packer.MultiError
errs = packer.MultiErrorAppend(errs, p.config.AccessConfig.Prepare(&p.config.ctx)...)
if len(p.config.Paths) == 0 { if len(p.config.Paths) == 0 {
errs = packer.MultiErrorAppend( errs = packer.MultiErrorAppend(
@ -100,31 +95,6 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
} }
} }
// provision config by OS environment variables
if p.config.Token == "" {
p.config.Token = os.Getenv("YC_TOKEN")
}
if p.config.ServiceAccountKeyFile == "" {
p.config.ServiceAccountKeyFile = os.Getenv("YC_SERVICE_ACCOUNT_KEY_FILE")
}
if p.config.Token != "" && p.config.ServiceAccountKeyFile != "" {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("one of token or service account key file must be specified, not both"))
}
if p.config.Token != "" {
packer.LogSecretFilter.Set(p.config.Token)
}
if p.config.ServiceAccountKeyFile != "" {
if _, err := iamkey.ReadFromJSONFile(p.config.ServiceAccountKeyFile); err != nil {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("fail to read service account key file: %s", err))
}
}
if p.config.FolderID == "" { if p.config.FolderID == "" {
p.config.FolderID = os.Getenv("YC_FOLDER_ID") p.config.FolderID = os.Getenv("YC_FOLDER_ID")
} }
@ -203,8 +173,6 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
} }
yandexConfig := ycSaneDefaults() yandexConfig := ycSaneDefaults()
yandexConfig.Token = p.config.Token
yandexConfig.ServiceAccountKeyFile = p.config.ServiceAccountKeyFile
yandexConfig.DiskName = exporterName yandexConfig.DiskName = exporterName
yandexConfig.InstanceName = exporterName yandexConfig.InstanceName = exporterName
yandexConfig.DiskSizeGb = p.config.DiskSizeGb yandexConfig.DiskSizeGb = p.config.DiskSizeGb
@ -221,7 +189,7 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
yandexConfig.PlatformID = p.config.PlatformID yandexConfig.PlatformID = p.config.PlatformID
} }
driver, err := yandex.NewDriverYC(ui, &yandexConfig) driver, err := yandex.NewDriverYC(ui, &p.config.AccessConfig)
if err != nil { if err != nil {
return nil, false, false, err return nil, false, false, err
} }

View File

@ -16,6 +16,10 @@ type FlatConfig struct {
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"` PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"` PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"`
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"` PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"`
Endpoint *string `mapstructure:"endpoint" required:"false" cty:"endpoint" hcl:"endpoint"`
ServiceAccountKeyFile *string `mapstructure:"service_account_key_file" required:"false" cty:"service_account_key_file" hcl:"service_account_key_file"`
Token *string `mapstructure:"token" required:"true" cty:"token" hcl:"token"`
MaxRetries *int `mapstructure:"max_retries" cty:"max_retries" hcl:"max_retries"`
Paths []string `mapstructure:"paths" required:"true" cty:"paths" hcl:"paths"` Paths []string `mapstructure:"paths" required:"true" cty:"paths" hcl:"paths"`
FolderID *string `mapstructure:"folder_id" required:"true" cty:"folder_id" hcl:"folder_id"` FolderID *string `mapstructure:"folder_id" required:"true" cty:"folder_id" hcl:"folder_id"`
ServiceAccountID *string `mapstructure:"service_account_id" required:"true" cty:"service_account_id" hcl:"service_account_id"` ServiceAccountID *string `mapstructure:"service_account_id" required:"true" cty:"service_account_id" hcl:"service_account_id"`
@ -24,8 +28,6 @@ type FlatConfig struct {
PlatformID *string `mapstructure:"platform_id" required:"false" cty:"platform_id" hcl:"platform_id"` PlatformID *string `mapstructure:"platform_id" required:"false" cty:"platform_id" hcl:"platform_id"`
SubnetID *string `mapstructure:"subnet_id" required:"false" cty:"subnet_id" hcl:"subnet_id"` SubnetID *string `mapstructure:"subnet_id" required:"false" cty:"subnet_id" hcl:"subnet_id"`
Zone *string `mapstructure:"zone" required:"false" cty:"zone" hcl:"zone"` Zone *string `mapstructure:"zone" required:"false" cty:"zone" hcl:"zone"`
Token *string `mapstructure:"token" required:"false" cty:"token" hcl:"token"`
ServiceAccountKeyFile *string `mapstructure:"service_account_key_file" required:"false" cty:"service_account_key_file" hcl:"service_account_key_file"`
} }
// FlatMapstructure returns a new FlatConfig. // FlatMapstructure returns a new FlatConfig.
@ -47,6 +49,10 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false}, "packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
"packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false}, "packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false},
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false}, "packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
"endpoint": &hcldec.AttrSpec{Name: "endpoint", Type: cty.String, Required: false},
"service_account_key_file": &hcldec.AttrSpec{Name: "service_account_key_file", Type: cty.String, Required: false},
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
"max_retries": &hcldec.AttrSpec{Name: "max_retries", Type: cty.Number, Required: false},
"paths": &hcldec.AttrSpec{Name: "paths", Type: cty.List(cty.String), Required: false}, "paths": &hcldec.AttrSpec{Name: "paths", Type: cty.List(cty.String), Required: false},
"folder_id": &hcldec.AttrSpec{Name: "folder_id", Type: cty.String, Required: false}, "folder_id": &hcldec.AttrSpec{Name: "folder_id", Type: cty.String, Required: false},
"service_account_id": &hcldec.AttrSpec{Name: "service_account_id", Type: cty.String, Required: false}, "service_account_id": &hcldec.AttrSpec{Name: "service_account_id", Type: cty.String, Required: false},
@ -55,8 +61,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"platform_id": &hcldec.AttrSpec{Name: "platform_id", Type: cty.String, Required: false}, "platform_id": &hcldec.AttrSpec{Name: "platform_id", Type: cty.String, Required: false},
"subnet_id": &hcldec.AttrSpec{Name: "subnet_id", Type: cty.String, Required: false}, "subnet_id": &hcldec.AttrSpec{Name: "subnet_id", Type: cty.String, Required: false},
"zone": &hcldec.AttrSpec{Name: "zone", Type: cty.String, Required: false}, "zone": &hcldec.AttrSpec{Name: "zone", Type: cty.String, Required: false},
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
"service_account_key_file": &hcldec.AttrSpec{Name: "service_account_key_file", Type: cty.String, Required: false},
} }
return s return s
} }

View File

@ -3,6 +3,7 @@ package yandexexport
import ( import (
"testing" "testing"
"github.com/hashicorp/packer/builder/yandex"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/helper/multistep"
@ -26,8 +27,10 @@ func TestPostProcessor_Configure(t *testing.T) {
name: "no one creds", name: "no one creds",
fields: fields{ fields: fields{
config: Config{ config: Config{
Token: "", AccessConfig: yandex.AccessConfig{
ServiceAccountKeyFile: "", Token: "",
ServiceAccountKeyFile: "",
},
}, },
}, },
wantErr: false, wantErr: false,
@ -36,8 +39,10 @@ func TestPostProcessor_Configure(t *testing.T) {
name: "both token and sa key file", name: "both token and sa key file",
fields: fields{ fields: fields{
config: Config{ config: Config{
Token: "some-value", AccessConfig: yandex.AccessConfig{
ServiceAccountKeyFile: "path/not-exist.file", Token: "some-value",
ServiceAccountKeyFile: "path/not-exist.file",
},
}, },
}, },
wantErr: true, wantErr: true,
@ -46,8 +51,10 @@ func TestPostProcessor_Configure(t *testing.T) {
name: "use sa key file", name: "use sa key file",
fields: fields{ fields: fields{
config: Config{ config: Config{
Token: "", AccessConfig: yandex.AccessConfig{
ServiceAccountKeyFile: "testdata/fake-sa-key.json", Token: "",
ServiceAccountKeyFile: "testdata/fake-sa-key.json",
},
}, },
}, },
wantErr: false, wantErr: false,

View File

@ -19,24 +19,18 @@ import (
yandexexport "github.com/hashicorp/packer/post-processor/yandex-export" yandexexport "github.com/hashicorp/packer/post-processor/yandex-export"
"github.com/hashicorp/packer/template/interpolate" "github.com/hashicorp/packer/template/interpolate"
"github.com/yandex-cloud/go-genproto/yandex/cloud/iam/v1/awscompatibility" "github.com/yandex-cloud/go-genproto/yandex/cloud/iam/v1/awscompatibility"
"github.com/yandex-cloud/go-sdk/iamkey"
) )
type Config struct { type Config struct {
common.PackerConfig `mapstructure:",squash"` common.PackerConfig `mapstructure:",squash"`
yandex.AccessConfig `mapstructure:",squash"`
// The folder ID that will be used to store imported Image. // The folder ID that will be used to store imported Image.
FolderID string `mapstructure:"folder_id" required:"true"` FolderID string `mapstructure:"folder_id" required:"true"`
// Service Account ID with proper permission to use Storage service // Service Account ID with proper permission to use Storage service
// for operations 'upload' and 'delete' object to `bucket` // for operations 'upload' and 'delete' object to `bucket`.
ServiceAccountID string `mapstructure:"service_account_id" required:"true"` ServiceAccountID string `mapstructure:"service_account_id" required:"true"`
// OAuth token to use to authenticate to Yandex.Cloud.
Token string `mapstructure:"token" required:"false"`
// Path to file with Service Account key in json format. This
// is an alternative method to authenticate to Yandex.Cloud.
ServiceAccountKeyFile string `mapstructure:"service_account_key_file" required:"false"`
// The name of the bucket where the qcow2 file will be uploaded to for import. // The name of the bucket where the qcow2 file will be uploaded to for import.
// This bucket must exist when the post-processor is run. // This bucket must exist when the post-processor is run.
// //
@ -49,7 +43,7 @@ type Config struct {
ObjectName string `mapstructure:"object_name" required:"false"` ObjectName string `mapstructure:"object_name" required:"false"`
// Whether skip removing the qcow2 file uploaded to Storage // Whether skip removing the qcow2 file uploaded to Storage
// after the import process has completed. Possible values are: `true` to // after the import process has completed. Possible values are: `true` to
// leave it in the bucket, `false` to remove it. (Default: `false`). // leave it in the bucket, `false` to remove it. Default is `false`.
SkipClean bool `mapstructure:"skip_clean" required:"false"` SkipClean bool `mapstructure:"skip_clean" required:"false"`
// The name of the image, which contains 1-63 characters and only // The name of the image, which contains 1-63 characters and only
@ -85,27 +79,10 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
return err return err
} }
errs := new(packer.MultiError) // Accumulate any errors
var errs *packer.MultiError
// provision config by OS environment variables errs = packer.MultiErrorAppend(errs, p.config.AccessConfig.Prepare(&p.config.ctx)...)
if p.config.Token == "" {
p.config.Token = os.Getenv("YC_TOKEN")
}
if p.config.ServiceAccountKeyFile == "" {
p.config.ServiceAccountKeyFile = os.Getenv("YC_SERVICE_ACCOUNT_KEY_FILE")
}
if p.config.Token != "" {
packer.LogSecretFilter.Set(p.config.Token)
}
if p.config.ServiceAccountKeyFile != "" {
if _, err := iamkey.ReadFromJSONFile(p.config.ServiceAccountKeyFile); err != nil {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("fail to read service account key file: %s", err))
}
}
if p.config.FolderID == "" { if p.config.FolderID == "" {
p.config.FolderID = os.Getenv("YC_FOLDER_ID") p.config.FolderID = os.Getenv("YC_FOLDER_ID")
@ -160,12 +137,8 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
return nil, false, false, fmt.Errorf("error rendering object_name template: %s", err) return nil, false, false, fmt.Errorf("error rendering object_name template: %s", err)
} }
cfg := &yandex.Config{ client, err := yandex.NewDriverYC(ui, &p.config.AccessConfig)
Token: p.config.Token,
ServiceAccountKeyFile: p.config.ServiceAccountKeyFile,
}
client, err := yandex.NewDriverYC(ui, cfg)
if err != nil { if err != nil {
return nil, false, false, err return nil, false, false, err
} }

View File

@ -16,10 +16,12 @@ type FlatConfig struct {
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"` PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"` PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"`
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"` PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"`
Endpoint *string `mapstructure:"endpoint" required:"false" cty:"endpoint" hcl:"endpoint"`
ServiceAccountKeyFile *string `mapstructure:"service_account_key_file" required:"false" cty:"service_account_key_file" hcl:"service_account_key_file"`
Token *string `mapstructure:"token" required:"true" cty:"token" hcl:"token"`
MaxRetries *int `mapstructure:"max_retries" cty:"max_retries" hcl:"max_retries"`
FolderID *string `mapstructure:"folder_id" required:"true" cty:"folder_id" hcl:"folder_id"` FolderID *string `mapstructure:"folder_id" required:"true" cty:"folder_id" hcl:"folder_id"`
ServiceAccountID *string `mapstructure:"service_account_id" required:"true" cty:"service_account_id" hcl:"service_account_id"` ServiceAccountID *string `mapstructure:"service_account_id" required:"true" cty:"service_account_id" hcl:"service_account_id"`
Token *string `mapstructure:"token" required:"false" cty:"token" hcl:"token"`
ServiceAccountKeyFile *string `mapstructure:"service_account_key_file" required:"false" cty:"service_account_key_file" hcl:"service_account_key_file"`
Bucket *string `mapstructure:"bucket" required:"false" cty:"bucket" hcl:"bucket"` Bucket *string `mapstructure:"bucket" required:"false" cty:"bucket" hcl:"bucket"`
ObjectName *string `mapstructure:"object_name" required:"false" cty:"object_name" hcl:"object_name"` ObjectName *string `mapstructure:"object_name" required:"false" cty:"object_name" hcl:"object_name"`
SkipClean *bool `mapstructure:"skip_clean" required:"false" cty:"skip_clean" hcl:"skip_clean"` SkipClean *bool `mapstructure:"skip_clean" required:"false" cty:"skip_clean" hcl:"skip_clean"`
@ -48,10 +50,12 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false}, "packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
"packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false}, "packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false},
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false}, "packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
"endpoint": &hcldec.AttrSpec{Name: "endpoint", Type: cty.String, Required: false},
"service_account_key_file": &hcldec.AttrSpec{Name: "service_account_key_file", Type: cty.String, Required: false},
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
"max_retries": &hcldec.AttrSpec{Name: "max_retries", Type: cty.Number, Required: false},
"folder_id": &hcldec.AttrSpec{Name: "folder_id", Type: cty.String, Required: false}, "folder_id": &hcldec.AttrSpec{Name: "folder_id", Type: cty.String, Required: false},
"service_account_id": &hcldec.AttrSpec{Name: "service_account_id", Type: cty.String, Required: false}, "service_account_id": &hcldec.AttrSpec{Name: "service_account_id", Type: cty.String, Required: false},
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
"service_account_key_file": &hcldec.AttrSpec{Name: "service_account_key_file", Type: cty.String, Required: false},
"bucket": &hcldec.AttrSpec{Name: "bucket", Type: cty.String, Required: false}, "bucket": &hcldec.AttrSpec{Name: "bucket", Type: cty.String, Required: false},
"object_name": &hcldec.AttrSpec{Name: "object_name", Type: cty.String, Required: false}, "object_name": &hcldec.AttrSpec{Name: "object_name", Type: cty.String, Required: false},
"skip_clean": &hcldec.AttrSpec{Name: "skip_clean", Type: cty.Bool, Required: false}, "skip_clean": &hcldec.AttrSpec{Name: "skip_clean", Type: cty.Bool, Required: false},

View File

@ -67,12 +67,15 @@ can be configured for this builder.
### Required: ### Required:
@include 'builder/yandex/AccessConfig-required.mdx'
@include 'builder/yandex/Config-required.mdx' @include 'builder/yandex/Config-required.mdx'
### Optional: ### Optional:
@include 'builder/yandex/Config-not-required.mdx' @include 'builder/yandex/AccessConfig-not-required.mdx'
@include 'builder/yandex/Config-not-required.mdx'
## Build template data ## Build template data

View File

@ -33,10 +33,14 @@ image.
### Required: ### Required:
@include 'builder/yandex/AccessConfig-required.mdx'
@include 'post-processor/yandex-export/Config-required.mdx' @include 'post-processor/yandex-export/Config-required.mdx'
### Optional: ### Optional:
@include 'builder/yandex/AccessConfig-not-required.mdx'
@include 'post-processor/yandex-export/Config-not-required.mdx' @include 'post-processor/yandex-export/Config-not-required.mdx'
## Basic Example ## Basic Example

View File

@ -25,10 +25,14 @@ file.
### Required: ### Required:
@include 'builder/yandex/AccessConfig-required.mdx'
@include 'post-processor/yandex-import/Config-required.mdx' @include 'post-processor/yandex-import/Config-required.mdx'
### Optional: ### Optional:
@include 'builder/yandex/AccessConfig-not-required.mdx'
@include 'post-processor/yandex-import/Config-not-required.mdx' @include 'post-processor/yandex-import/Config-not-required.mdx'
## Basic Example ## Basic Example

View File

@ -0,0 +1,9 @@
<!-- Code generated from the comments of the AccessConfig struct in builder/yandex/access_config.go; DO NOT EDIT MANUALLY -->
- `endpoint` (string) - Non standard API endpoint. Default is `api.cloud.yandex.net:443`.
- `service_account_key_file` (string) - Path to file with Service Account key in json format. This
is an alternative method to authenticate to Yandex.Cloud. Alternatively you may set environment variable
`YC_SERVICE_ACCOUNT_KEY_FILE`.
- `max_retries` (int) - The maximum number of times an API request is being executed.

View File

@ -0,0 +1,4 @@
<!-- Code generated from the comments of the AccessConfig struct in builder/yandex/access_config.go; DO NOT EDIT MANUALLY -->
- `token` (string) - OAuth token to use to authenticate to Yandex.Cloud. Alternatively you may set
value by environment variable `YC_TOKEN`.

View File

@ -0,0 +1,3 @@
<!-- Code generated from the comments of the AccessConfig struct in builder/yandex/access_config.go; DO NOT EDIT MANUALLY -->
AccessConfig is for common configuration related to Yandex.Cloud API access

View File

@ -1,12 +1,6 @@
<!-- Code generated from the comments of the Config struct in builder/yandex/config.go; DO NOT EDIT MANUALLY --> <!-- Code generated from the comments of the Config struct in builder/yandex/config.go; DO NOT EDIT MANUALLY -->
- `endpoint` (string) - Non standard api endpoint URL. - `service_account_id` (string) - Service account identifier to assign to instance.
- `service_account_key_file` (string) - Path to file with Service Account key in json format. This
is an alternative method to authenticate to Yandex.Cloud. Alternatively you may set environment variable
YC_SERVICE_ACCOUNT_KEY_FILE.
- `service_account_id` (string) - Service account identifier to assign to instance
- `disk_name` (string) - The name of the disk, if unset the instance name - `disk_name` (string) - The name of the disk, if unset the instance name
will be used. will be used.
@ -19,8 +13,7 @@
- `image_family` (string) - The family name of the resulting image. - `image_family` (string) - The family name of the resulting image.
- `image_labels` (map[string]string) - Key/value pair labels to - `image_labels` (map[string]string) - Key/value pair labels to apply to the created image.
apply to the created image.
- `image_min_disk_size_gb` (int) - Minimum size of the disk that will be created from built image, specified in gigabytes. - `image_min_disk_size_gb` (int) - Minimum size of the disk that will be created from built image, specified in gigabytes.
Should be more or equal to `disk_size_gb`. Should be more or equal to `disk_size_gb`.
@ -38,16 +31,14 @@
- `instance_name` (string) - The name assigned to the instance. - `instance_name` (string) - The name assigned to the instance.
- `labels` (map[string]string) - Key/value pair labels to apply to - `labels` (map[string]string) - Key/value pair labels to apply to the launched instance.
the launched instance.
- `platform_id` (string) - Identifier of the hardware platform configuration for the instance. This defaults to `standard-v1`. - `platform_id` (string) - Identifier of the hardware platform configuration for the instance. This defaults to `standard-v1`.
- `max_retries` (int) - The maximum number of times an API request is being executed
- `metadata` (map[string]string) - Metadata applied to the launched instance. - `metadata` (map[string]string) - Metadata applied to the launched instance.
- `metadata_from_file` (map[string]string) - Metadata applied to the launched instance. Value are file paths. - `metadata_from_file` (map[string]string) - Metadata applied to the launched instance.
The values in this map are the paths to the content files for the corresponding metadata keys.
- `preemptible` (bool) - Launch a preemptible instance. This defaults to `false`. - `preemptible` (bool) - Launch a preemptible instance. This defaults to `false`.
@ -55,8 +46,7 @@
- `source_image_folder_id` (string) - The ID of the folder containing the source image. - `source_image_folder_id` (string) - The ID of the folder containing the source image.
- `source_image_id` (string) - The source image ID to use to create the new image - `source_image_id` (string) - The source image ID to use to create the new image from.
from.
- `source_image_name` (string) - The source image name to use to create the new image - `source_image_name` (string) - The source image name to use to create the new image
from. Name will be looked up in `source_image_folder_id`. from. Name will be looked up in `source_image_folder_id`.

View File

@ -1,13 +1,10 @@
<!-- Code generated from the comments of the Config struct in builder/yandex/config.go; DO NOT EDIT MANUALLY --> <!-- Code generated from the comments of the Config struct in builder/yandex/config.go; DO NOT EDIT MANUALLY -->
- `folder_id` (string) - The folder ID that will be used to launch instances and store images. - `folder_id` (string) - The folder ID that will be used to launch instances and store images.
Alternatively you may set value by environment variable YC_FOLDER_ID. Alternatively you may set value by environment variable `YC_FOLDER_ID`.
To use a different folder for looking up the source image or saving the target image to To use a different folder for looking up the source image or saving the target image to
check options 'source_image_folder_id' and 'target_image_folder_id'. check options 'source_image_folder_id' and 'target_image_folder_id'.
- `token` (string) - OAuth token to use to authenticate to Yandex.Cloud. Alternatively you may set
value by environment variable YC_TOKEN.
- `source_image_family` (string) - The source image family to create the new image - `source_image_family` (string) - The source image family to create the new image
from. You can also specify source_image_id instead. Just one of a source_image_id or from. You can also specify source_image_id instead. Just one of a source_image_id or
source_image_family must be specified. Example: `ubuntu-1804-lts` source_image_family must be specified. Example: `ubuntu-1804-lts`.

View File

@ -11,10 +11,3 @@
zone in which the VM is launched. zone in which the VM is launched.
- `zone` (string) - The name of the zone to launch the instance. This defaults to `ru-central1-a`. - `zone` (string) - The name of the zone to launch the instance. This defaults to `ru-central1-a`.
- `token` (string) - OAuth token to use to authenticate to Yandex.Cloud. Alternatively you may set
value by environment variable YC_TOKEN.
- `service_account_key_file` (string) - Path to file with Service Account key in json format. This
is an alternative method to authenticate to Yandex.Cloud. Alternatively you may set environment variable
YC_SERVICE_ACCOUNT_KEY_FILE.

View File

@ -7,7 +7,7 @@
Paths to Yandex Object Storage where exported image will be uploaded. Paths to Yandex Object Storage where exported image will be uploaded.
- `folder_id` (string) - The folder ID that will be used to launch a temporary instance. - `folder_id` (string) - The folder ID that will be used to launch a temporary instance.
Alternatively you may set value by environment variable YC_FOLDER_ID. Alternatively you may set value by environment variable `YC_FOLDER_ID`.
- `service_account_id` (string) - Service Account ID with proper permission to modify an instance, create and attach disk and - `service_account_id` (string) - Service Account ID with proper permission to modify an instance, create and attach disk and
make upload to specific Yandex Object Storage paths. make upload to specific Yandex Object Storage paths.

View File

@ -1,10 +1,5 @@
<!-- Code generated from the comments of the Config struct in post-processor/yandex-import/post-processor.go; DO NOT EDIT MANUALLY --> <!-- Code generated from the comments of the Config struct in post-processor/yandex-import/post-processor.go; DO NOT EDIT MANUALLY -->
- `token` (string) - OAuth token to use to authenticate to Yandex.Cloud.
- `service_account_key_file` (string) - Path to file with Service Account key in json format. This
is an alternative method to authenticate to Yandex.Cloud.
- `bucket` (string) - The name of the bucket where the qcow2 file will be uploaded to for import. - `bucket` (string) - The name of the bucket where the qcow2 file will be uploaded to for import.
This bucket must exist when the post-processor is run. This bucket must exist when the post-processor is run.
@ -17,7 +12,7 @@
- `skip_clean` (bool) - Whether skip removing the qcow2 file uploaded to Storage - `skip_clean` (bool) - Whether skip removing the qcow2 file uploaded to Storage
after the import process has completed. Possible values are: `true` to after the import process has completed. Possible values are: `true` to
leave it in the bucket, `false` to remove it. (Default: `false`). leave it in the bucket, `false` to remove it. Default is `false`.
- `image_name` (string) - The name of the image, which contains 1-63 characters and only - `image_name` (string) - The name of the image, which contains 1-63 characters and only
supports lowercase English characters, numbers and hyphen. supports lowercase English characters, numbers and hyphen.

View File

@ -3,4 +3,4 @@
- `folder_id` (string) - The folder ID that will be used to store imported Image. - `folder_id` (string) - The folder ID that will be used to store imported Image.
- `service_account_id` (string) - Service Account ID with proper permission to use Storage service - `service_account_id` (string) - Service Account ID with proper permission to use Storage service
for operations 'upload' and 'delete' object to `bucket` for operations 'upload' and 'delete' object to `bucket`.