Triton plugin breakout (#10963)

This commit is contained in:
Adrien Delorme 2021-04-22 14:06:30 +02:00 committed by GitHub
parent f161f2bed2
commit 2cd296874e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 100 additions and 2268 deletions

View File

@ -1,195 +0,0 @@
//go:generate packer-sdc struct-markdown
package triton
import (
"errors"
"fmt"
"io/ioutil"
"os"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/packer-plugin-sdk/communicator"
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
tgo "github.com/joyent/triton-go"
"github.com/joyent/triton-go/authentication"
"github.com/joyent/triton-go/compute"
"github.com/joyent/triton-go/network"
)
// AccessConfig is for common configuration related to Triton access
type AccessConfig struct {
// The URL of the Triton cloud API to use. If omitted
// it will default to the us-sw-1 region of the Joyent Public cloud. If you
// are using your own private Triton installation you will have to supply the
// URL of the cloud API of your own Triton installation.
Endpoint string `mapstructure:"triton_url" required:"false"`
// The username of the Triton account to use when
// using the Triton Cloud API.
Account string `mapstructure:"triton_account" required:"true"`
// The username of a user who has access to your
// Triton account.
Username string `mapstructure:"triton_user" required:"false"`
// The fingerprint of the public key of the SSH key
// pair to use for authentication with the Triton Cloud API. If
// triton_key_material is not set, it is assumed that the SSH agent has the
// private key corresponding to this key ID loaded.
KeyID string `mapstructure:"triton_key_id" required:"true"`
// Path to the file in which the private key
// of triton_key_id is stored. For example /home/soandso/.ssh/id_rsa. If
// this is not specified, the SSH agent is used to sign requests with the
// triton_key_id specified.
KeyMaterial string `mapstructure:"triton_key_material" required:"false"`
//secure_skip_tls_verify - (bool) This allows skipping TLS verification
// of the Triton endpoint. It is useful when connecting to a temporary Triton
// installation such as Cloud-On-A-Laptop which does not generally use a
// certificate signed by a trusted root CA. The default is false.
InsecureSkipTLSVerify bool `mapstructure:"insecure_skip_tls_verify" required:"false"`
signer authentication.Signer
}
// Prepare performs basic validation on the AccessConfig and ensures we can sign
// a request.
func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
var errs []error
if c.Endpoint == "" {
// Use Joyent public cloud as the default endpoint if none is specified
c.Endpoint = "https://us-sw-1.api.joyent.com"
}
if c.Account == "" {
errs = append(errs, errors.New("triton_account is required to use the triton builder"))
}
if c.KeyID == "" {
errs = append(errs, errors.New("triton_key_id is required to use the triton builder"))
}
if c.KeyMaterial == "" {
signer, err := c.createSSHAgentSigner()
if err != nil {
errs = append(errs, err)
}
c.signer = signer
} else {
signer, err := c.createPrivateKeySigner()
if err != nil {
errs = append(errs, err)
}
c.signer = signer
}
if len(errs) > 0 {
return errs
}
return nil
}
func (c *AccessConfig) createSSHAgentSigner() (authentication.Signer, error) {
input := authentication.SSHAgentSignerInput{
KeyID: c.KeyID,
AccountName: c.Account,
Username: c.Username,
}
signer, err := authentication.NewSSHAgentSigner(input)
if err != nil {
return nil, fmt.Errorf("Error creating Triton request signer: %s", err)
}
// Ensure we can sign a request
_, err = signer.Sign("Wed, 26 Apr 2017 16:01:11 UTC", false)
if err != nil {
return nil, fmt.Errorf("Error signing test request: %s", err)
}
return signer, nil
}
func (c *AccessConfig) createPrivateKeySigner() (authentication.Signer, error) {
var privateKeyMaterial []byte
var err error
// Check for keyMaterial being a file path
if _, err = os.Stat(c.KeyMaterial); err != nil {
privateKeyMaterial = []byte(c.KeyMaterial)
} else {
privateKeyMaterial, err = ioutil.ReadFile(c.KeyMaterial)
if err != nil {
return nil, fmt.Errorf("Error reading key material from path '%s': %s",
c.KeyMaterial, err)
}
}
input := authentication.PrivateKeySignerInput{
KeyID: c.KeyID,
AccountName: c.Account,
Username: c.Username,
PrivateKeyMaterial: privateKeyMaterial,
}
signer, err := authentication.NewPrivateKeySigner(input)
if err != nil {
return nil, fmt.Errorf("Error creating Triton request signer: %s", err)
}
// Ensure we can sign a request
_, err = signer.Sign("Wed, 26 Apr 2017 16:01:11 UTC", false)
if err != nil {
return nil, fmt.Errorf("Error signing test request: %s", err)
}
return signer, nil
}
func (c *AccessConfig) CreateTritonClient() (*Client, error) {
config := &tgo.ClientConfig{
AccountName: c.Account,
TritonURL: c.Endpoint,
Username: c.Username,
Signers: []authentication.Signer{c.signer},
}
return &Client{
config: config,
insecureSkipTLSVerify: c.InsecureSkipTLSVerify,
}, nil
}
type Client struct {
config *tgo.ClientConfig
insecureSkipTLSVerify bool
}
func (c *Client) Compute() (*compute.ComputeClient, error) {
computeClient, err := compute.NewClient(c.config)
if err != nil {
return nil, errwrap.Wrapf("Error Creating Triton Compute Client: {{err}}", err)
}
if c.insecureSkipTLSVerify {
computeClient.Client.InsecureSkipTLSVerify()
}
return computeClient, nil
}
func (c *Client) Network() (*network.NetworkClient, error) {
networkClient, err := network.NewClient(c.config)
if err != nil {
return nil, errwrap.Wrapf("Error Creating Triton Network Client: {{err}}", err)
}
if c.insecureSkipTLSVerify {
networkClient.Client.InsecureSkipTLSVerify()
}
return networkClient, nil
}
func (c *AccessConfig) Comm() communicator.Config {
return communicator.Config{}
}

View File

@ -1,64 +0,0 @@
package triton
import (
"testing"
)
func TestAccessConfig_Prepare(t *testing.T) {
ac := testAccessConfig()
errs := ac.Prepare(nil)
if errs != nil {
t.Fatal("should not error")
}
ac = testAccessConfig()
ac.Account = ""
errs = ac.Prepare(nil)
if errs == nil {
t.Fatal("should error")
}
ac = testAccessConfig()
ac.KeyID = ""
errs = ac.Prepare(nil)
if errs == nil {
t.Fatal("should error")
}
}
func testAccessConfig() AccessConfig {
return AccessConfig{
Endpoint: "test-endpoint",
Account: "test-account",
KeyID: "c5:9d:37:d2:28:d3:ef:39:1b:0a:0e:37:d5:b4:7c:59",
KeyMaterial: testKeyMaterial,
}
}
const testKeyMaterial = `-----BEGIN RSA PRIVATE KEY-----
MIIEpgIBAAKCAQEAuujYxDCBu9W6es650mLcy9RaLGqjHT2KXPs4fHVr1sfBxPDk
ChpekrVEfE69wpf7/oduQwLmBTIBBNtr/aH5e8gt2uCe1kD6swjnAG+nWZB63/BW
XF9zFFE/Vs/dOyHIkqoLhVHurYYFBGqDXH4w1N02vfyQaH/VQDumF9ZiH6b9u28/
WtrHSLPeGidgrt3csh0Q4Bydm2xSCx4Kfeouv0rM25mFoiq/QaTXkfWS0sIzrhhU
rXL4N6B8tBRojHghpjh8LjG4ufJ7Q0QMWfeBfTqQ9llaEtiMIBznyq+oF7vwv0pc
Cw2eXcURfg/9e5M8S3gSthkqGN9NjQUSeNsgCQIDAQABAoIBAQCcy6zcmFyc+GTh
lP5psanMDC5BSIvhgbjK26y9K7v1h8nTrsl+eDSSGiKDrYKe9eTd1zr2WD4iaZpV
OsVTFkg2QO3Gydw1nHkzK+qtgP0As6WAqxunjiL6DlZ2OxY5/tNFxgS4KM1zIBSh
acEdHHdWeuTraC60m1iH9AIXyS6zoW+YvKr3Cu+gjQgDxg90Uzx7gB7/tAT9uTCG
NHXRCJFrjLlKwWap5QpbbrEMZXjwwb4FEC6KOWaTHDGtB6V2NHBYfpAucuLXx19H
jKUnogZHxTFbYwf7oZSVCR6tUm/Dytq0DmZv+wkCtUSqP0hljqO71yOOMiWA7fVq
4cyD8TGJAoGBAPVVebrIEm8gMTt7s37YFwZXXcC2GT/jVi5bOhWhL5zOA0VxJMH7
hUmrRNffNbFciSUM7CeSqh7Zq9v2l+qCjy9iZfUN6NY1s7d5q7NVkVX/GBuZ8ULp
d81L4ifnr9KsEIzWz8X3Y/efO/20YqoEqLJm6qUyZYHWJbv9Z8Cteef7AoGBAMMJ
HkzRop/VAi5RFzuJyNEzeOyveGpngtsnAY/UcEeWoxkUfHy/GAZAH8aAz9FqLaBv
xGL++g3l8nHtov+gkrnJpK/f0QEWY+PbRWxSRHLW0rBdQJRB8nisNrWJwj4ysNhj
ejYgBfSSmwkLBnvjNce6RwtZ5d+VRFGRl63CfMTLAoGBAK7Vaxqg2gI3ft5VGWWb
uUzblgRvwS62ZARFHu+rHrMwXURvjTJwfFwzoav1dd4fg9zTiLfq3TF/DeqDoV+O
C1xJUz9/2h5NxvVJ0ALNR/VxBU0mN7jniGjVWyX1BmesF19G9mquEp+06puyoV1o
VJBOp4lykMQmSF3gCMBW4DlhAoGBAINdauk28iBRqqxjthBGF9rAnpxc+/A/VCYk
OasU3aN6VNSZtdeYJqhfHIfpTxCwQZckcNR1BRvDW+9crkMbdnho1uIXEIF5AUMB
99qj9rKa+0ILLWoumRCqfhb8eLbIEdFN/4zhOOGotX/7yxw6x4iFcUC2Blz3/xIp
zE4fB0bNAoGBAK/ms0TixeqdNCY8WVHjT6H1W34Y1gvMlwSDodlUk0v8rUHAK4bO
TKvdCYbxCQ+kqAFlicY1ZwxoeJzW6k3K+kJ+qWBn0yH4W61M8uKOIvciu1w1CXxG
XZHg281yLxOfJj9YnPG73+sZFucyhtNPiq/1pR4tpm6YLMk8KSTy7XU5
-----END RSA PRIVATE KEY-----`

View File

@ -1,53 +0,0 @@
package triton
import (
"fmt"
"log"
)
// Artifact is an artifact implementation that contains built Triton images.
type Artifact struct {
// ImageID is the image ID of the artifact
ImageID string
// BuilderIDValue is the unique ID for the builder that created this Image
BuilderIDValue string
// SDC connection for cleanup etc
Driver Driver
// StateData should store data such as GeneratedData
// to be shared with post-processors
StateData map[string]interface{}
}
func (a *Artifact) BuilderId() string {
return a.BuilderIDValue
}
func (*Artifact) Files() []string {
return nil
}
func (a *Artifact) Id() string {
return a.ImageID
}
func (a *Artifact) String() string {
return fmt.Sprintf("Image was created: %s", a.ImageID)
}
func (a *Artifact) State(name string) interface{} {
//TODO(jen20): Figure out how to make this work with Atlas
return a.StateData[name]
}
func (a *Artifact) Destroy() error {
log.Printf("Deleting image ID (%s)", a.ImageID)
err := a.Driver.DeleteImage(a.ImageID)
if err != nil {
return err
}
return nil
}

View File

@ -1,107 +0,0 @@
package triton
import (
"context"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer-plugin-sdk/communicator"
"github.com/hashicorp/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer-plugin-sdk/multistep/commonsteps"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
"github.com/hashicorp/packer-plugin-sdk/template/config"
)
const (
BuilderId = "joyent.triton"
)
type Builder struct {
config Config
runner multistep.Runner
}
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
errs := &multierror.Error{}
err := config.Decode(&b.config, &config.DecodeOpts{
PluginType: BuilderId,
Interpolate: true,
InterpolateContext: &b.config.ctx,
}, raws...)
if err != nil {
errs = multierror.Append(errs, err)
}
errs = multierror.Append(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...)
errs = multierror.Append(errs, b.config.SourceMachineConfig.Prepare(&b.config.ctx)...)
errs = multierror.Append(errs, b.config.Comm.Prepare(&b.config.ctx)...)
errs = multierror.Append(errs, b.config.TargetImageConfig.Prepare(&b.config.ctx)...)
// If we are using an SSH agent to sign requests, and no private key has been
// specified for SSH, use the agent for connecting for provisioning.
if b.config.AccessConfig.KeyMaterial == "" && b.config.Comm.SSHPrivateKeyFile == "" {
b.config.Comm.SSHAgentAuth = true
}
return nil, nil, errs.ErrorOrNil()
}
func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook) (packersdk.Artifact, error) {
config := b.config
driver, err := NewDriverTriton(ui, config)
if err != nil {
return nil, err
}
state := new(multistep.BasicStateBag)
state.Put("config", &b.config)
state.Put("debug", b.config.PackerDebug)
state.Put("driver", driver)
state.Put("hook", hook)
state.Put("ui", ui)
steps := []multistep.Step{
&StepCreateSourceMachine{},
&communicator.StepConnect{
Config: &config.Comm,
Host: commHost(b.config.Comm.Host()),
SSHConfig: b.config.Comm.SSHConfigFunc(),
},
&commonsteps.StepProvision{},
&commonsteps.StepCleanupTempKeys{
Comm: &config.Comm,
},
&StepStopMachine{},
&StepCreateImageFromMachine{},
&StepDeleteMachine{},
}
b.runner = commonsteps.NewRunnerWithPauseFn(steps, b.config.PackerConfig, ui, state)
b.runner.Run(ctx, state)
// If there was an error, return that
if rawErr, ok := state.GetOk("error"); ok {
return nil, rawErr.(error)
}
// If there is no image, just return
if _, ok := state.GetOk("image"); !ok {
return nil, nil
}
artifact := &Artifact{
ImageID: state.Get("image").(string),
BuilderIDValue: BuilderId,
Driver: driver,
StateData: map[string]interface{}{"generated_data": state.Get("generated_data")},
}
return artifact, nil
}
// Cancel cancels a possibly running Builder. This should block until
// the builder actually cancels and cleans up after itself.

View File

@ -1,20 +0,0 @@
//go:generate packer-sdc mapstructure-to-hcl2 -type Config
package triton
import (
"github.com/hashicorp/packer-plugin-sdk/common"
"github.com/hashicorp/packer-plugin-sdk/communicator"
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
)
type Config struct {
common.PackerConfig `mapstructure:",squash"`
AccessConfig `mapstructure:",squash"`
SourceMachineConfig `mapstructure:",squash"`
TargetImageConfig `mapstructure:",squash"`
Comm communicator.Config `mapstructure:",squash"`
ctx interpolate.Context
}

View File

@ -1,190 +0,0 @@
// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT.
package triton
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer-plugin-sdk/template/config"
"github.com/zclconf/go-cty/cty"
)
// FlatConfig is an auto-generated flat version of Config.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatConfig struct {
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"`
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"`
PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"`
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"`
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"`
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"`
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"`
Endpoint *string `mapstructure:"triton_url" required:"false" cty:"triton_url" hcl:"triton_url"`
Account *string `mapstructure:"triton_account" required:"true" cty:"triton_account" hcl:"triton_account"`
Username *string `mapstructure:"triton_user" required:"false" cty:"triton_user" hcl:"triton_user"`
KeyID *string `mapstructure:"triton_key_id" required:"true" cty:"triton_key_id" hcl:"triton_key_id"`
KeyMaterial *string `mapstructure:"triton_key_material" required:"false" cty:"triton_key_material" hcl:"triton_key_material"`
InsecureSkipTLSVerify *bool `mapstructure:"insecure_skip_tls_verify" required:"false" cty:"insecure_skip_tls_verify" hcl:"insecure_skip_tls_verify"`
MachineName *string `mapstructure:"source_machine_name" required:"false" cty:"source_machine_name" hcl:"source_machine_name"`
MachinePackage *string `mapstructure:"source_machine_package" required:"true" cty:"source_machine_package" hcl:"source_machine_package"`
MachineImage *string `mapstructure:"source_machine_image" required:"true" cty:"source_machine_image" hcl:"source_machine_image"`
MachineNetworks []string `mapstructure:"source_machine_networks" required:"false" cty:"source_machine_networks" hcl:"source_machine_networks"`
MachineMetadata map[string]string `mapstructure:"source_machine_metadata" required:"false" cty:"source_machine_metadata" hcl:"source_machine_metadata"`
MachineTags map[string]string `mapstructure:"source_machine_tags" required:"false" cty:"source_machine_tags" hcl:"source_machine_tags"`
MachineTag []config.FlatKeyValue `mapstructure:"source_machine_tag" required:"false" cty:"source_machine_tag" hcl:"source_machine_tag"`
MachineFirewallEnabled *bool `mapstructure:"source_machine_firewall_enabled" required:"false" cty:"source_machine_firewall_enabled" hcl:"source_machine_firewall_enabled"`
MachineImageFilters *FlatMachineImageFilter `mapstructure:"source_machine_image_filter" required:"false" cty:"source_machine_image_filter" hcl:"source_machine_image_filter"`
ImageName *string `mapstructure:"image_name" required:"true" cty:"image_name" hcl:"image_name"`
ImageVersion *string `mapstructure:"image_version" required:"true" cty:"image_version" hcl:"image_version"`
ImageDescription *string `mapstructure:"image_description" required:"false" cty:"image_description" hcl:"image_description"`
ImageHomepage *string `mapstructure:"image_homepage" required:"false" cty:"image_homepage" hcl:"image_homepage"`
ImageEULA *string `mapstructure:"image_eula_url" required:"false" cty:"image_eula_url" hcl:"image_eula_url"`
ImageACL []string `mapstructure:"image_acls" required:"false" cty:"image_acls" hcl:"image_acls"`
ImageTags map[string]string `mapstructure:"image_tags" required:"false" cty:"image_tags" hcl:"image_tags"`
ImageTag []config.FlatNameValue `mapstructure:"image_tag" required:"false" cty:"image_tag" hcl:"image_tag"`
Type *string `mapstructure:"communicator" cty:"communicator" hcl:"communicator"`
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting" hcl:"pause_before_connecting"`
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host" hcl:"ssh_host"`
SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port" hcl:"ssh_port"`
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username" hcl:"ssh_username"`
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password" hcl:"ssh_password"`
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" undocumented:"true" cty:"ssh_keypair_name" hcl:"ssh_keypair_name"`
SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" undocumented:"true" cty:"temporary_key_pair_name" hcl:"temporary_key_pair_name"`
SSHTemporaryKeyPairType *string `mapstructure:"temporary_key_pair_type" cty:"temporary_key_pair_type" hcl:"temporary_key_pair_type"`
SSHTemporaryKeyPairBits *int `mapstructure:"temporary_key_pair_bits" cty:"temporary_key_pair_bits" hcl:"temporary_key_pair_bits"`
SSHCiphers []string `mapstructure:"ssh_ciphers" cty:"ssh_ciphers" hcl:"ssh_ciphers"`
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys" hcl:"ssh_clear_authorized_keys"`
SSHKEXAlgos []string `mapstructure:"ssh_key_exchange_algorithms" cty:"ssh_key_exchange_algorithms" hcl:"ssh_key_exchange_algorithms"`
SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" undocumented:"true" cty:"ssh_private_key_file" hcl:"ssh_private_key_file"`
SSHCertificateFile *string `mapstructure:"ssh_certificate_file" cty:"ssh_certificate_file" hcl:"ssh_certificate_file"`
SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty" hcl:"ssh_pty"`
SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout" hcl:"ssh_timeout"`
SSHWaitTimeout *string `mapstructure:"ssh_wait_timeout" undocumented:"true" cty:"ssh_wait_timeout" hcl:"ssh_wait_timeout"`
SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" undocumented:"true" cty:"ssh_agent_auth" hcl:"ssh_agent_auth"`
SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding" hcl:"ssh_disable_agent_forwarding"`
SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts" hcl:"ssh_handshake_attempts"`
SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host" hcl:"ssh_bastion_host"`
SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port" hcl:"ssh_bastion_port"`
SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth" hcl:"ssh_bastion_agent_auth"`
SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username" hcl:"ssh_bastion_username"`
SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password" hcl:"ssh_bastion_password"`
SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive" hcl:"ssh_bastion_interactive"`
SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file" hcl:"ssh_bastion_private_key_file"`
SSHBastionCertificateFile *string `mapstructure:"ssh_bastion_certificate_file" cty:"ssh_bastion_certificate_file" hcl:"ssh_bastion_certificate_file"`
SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method" hcl:"ssh_file_transfer_method"`
SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host" hcl:"ssh_proxy_host"`
SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port" hcl:"ssh_proxy_port"`
SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username" hcl:"ssh_proxy_username"`
SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password" hcl:"ssh_proxy_password"`
SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval" hcl:"ssh_keep_alive_interval"`
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout" hcl:"ssh_read_write_timeout"`
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels" hcl:"ssh_remote_tunnels"`
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels" hcl:"ssh_local_tunnels"`
SSHPublicKey []byte `mapstructure:"ssh_public_key" undocumented:"true" cty:"ssh_public_key" hcl:"ssh_public_key"`
SSHPrivateKey []byte `mapstructure:"ssh_private_key" undocumented:"true" cty:"ssh_private_key" hcl:"ssh_private_key"`
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username" hcl:"winrm_username"`
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password" hcl:"winrm_password"`
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host" hcl:"winrm_host"`
WinRMNoProxy *bool `mapstructure:"winrm_no_proxy" cty:"winrm_no_proxy" hcl:"winrm_no_proxy"`
WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port" hcl:"winrm_port"`
WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout" hcl:"winrm_timeout"`
WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl" hcl:"winrm_use_ssl"`
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"`
}
// FlatMapstructure returns a new FlatConfig.
// FlatConfig is an auto-generated flat version of Config.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatConfig)
}
// HCL2Spec returns the hcl spec of a Config.
// This spec is used by HCL to read the fields of Config.
// The decoded values from this spec will then be applied to a FlatConfig.
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
"packer_core_version": &hcldec.AttrSpec{Name: "packer_core_version", Type: cty.String, Required: false},
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, 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_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
"triton_url": &hcldec.AttrSpec{Name: "triton_url", Type: cty.String, Required: false},
"triton_account": &hcldec.AttrSpec{Name: "triton_account", Type: cty.String, Required: false},
"triton_user": &hcldec.AttrSpec{Name: "triton_user", Type: cty.String, Required: false},
"triton_key_id": &hcldec.AttrSpec{Name: "triton_key_id", Type: cty.String, Required: false},
"triton_key_material": &hcldec.AttrSpec{Name: "triton_key_material", Type: cty.String, Required: false},
"insecure_skip_tls_verify": &hcldec.AttrSpec{Name: "insecure_skip_tls_verify", Type: cty.Bool, Required: false},
"source_machine_name": &hcldec.AttrSpec{Name: "source_machine_name", Type: cty.String, Required: false},
"source_machine_package": &hcldec.AttrSpec{Name: "source_machine_package", Type: cty.String, Required: false},
"source_machine_image": &hcldec.AttrSpec{Name: "source_machine_image", Type: cty.String, Required: false},
"source_machine_networks": &hcldec.AttrSpec{Name: "source_machine_networks", Type: cty.List(cty.String), Required: false},
"source_machine_metadata": &hcldec.AttrSpec{Name: "source_machine_metadata", Type: cty.Map(cty.String), Required: false},
"source_machine_tags": &hcldec.AttrSpec{Name: "source_machine_tags", Type: cty.Map(cty.String), Required: false},
"source_machine_tag": &hcldec.BlockListSpec{TypeName: "source_machine_tag", Nested: hcldec.ObjectSpec((*config.FlatKeyValue)(nil).HCL2Spec())},
"source_machine_firewall_enabled": &hcldec.AttrSpec{Name: "source_machine_firewall_enabled", Type: cty.Bool, Required: false},
"source_machine_image_filter": &hcldec.BlockSpec{TypeName: "source_machine_image_filter", Nested: hcldec.ObjectSpec((*FlatMachineImageFilter)(nil).HCL2Spec())},
"image_name": &hcldec.AttrSpec{Name: "image_name", Type: cty.String, Required: false},
"image_version": &hcldec.AttrSpec{Name: "image_version", Type: cty.String, Required: false},
"image_description": &hcldec.AttrSpec{Name: "image_description", Type: cty.String, Required: false},
"image_homepage": &hcldec.AttrSpec{Name: "image_homepage", Type: cty.String, Required: false},
"image_eula_url": &hcldec.AttrSpec{Name: "image_eula_url", Type: cty.String, Required: false},
"image_acls": &hcldec.AttrSpec{Name: "image_acls", Type: cty.List(cty.String), Required: false},
"image_tags": &hcldec.AttrSpec{Name: "image_tags", Type: cty.Map(cty.String), Required: false},
"image_tag": &hcldec.BlockListSpec{TypeName: "image_tag", Nested: hcldec.ObjectSpec((*config.FlatNameValue)(nil).HCL2Spec())},
"communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false},
"pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false},
"ssh_host": &hcldec.AttrSpec{Name: "ssh_host", Type: cty.String, Required: false},
"ssh_port": &hcldec.AttrSpec{Name: "ssh_port", Type: cty.Number, Required: false},
"ssh_username": &hcldec.AttrSpec{Name: "ssh_username", Type: cty.String, Required: false},
"ssh_password": &hcldec.AttrSpec{Name: "ssh_password", Type: cty.String, Required: false},
"ssh_keypair_name": &hcldec.AttrSpec{Name: "ssh_keypair_name", Type: cty.String, Required: false},
"temporary_key_pair_name": &hcldec.AttrSpec{Name: "temporary_key_pair_name", Type: cty.String, Required: false},
"temporary_key_pair_type": &hcldec.AttrSpec{Name: "temporary_key_pair_type", Type: cty.String, Required: false},
"temporary_key_pair_bits": &hcldec.AttrSpec{Name: "temporary_key_pair_bits", Type: cty.Number, Required: false},
"ssh_ciphers": &hcldec.AttrSpec{Name: "ssh_ciphers", Type: cty.List(cty.String), Required: false},
"ssh_clear_authorized_keys": &hcldec.AttrSpec{Name: "ssh_clear_authorized_keys", Type: cty.Bool, Required: false},
"ssh_key_exchange_algorithms": &hcldec.AttrSpec{Name: "ssh_key_exchange_algorithms", Type: cty.List(cty.String), Required: false},
"ssh_private_key_file": &hcldec.AttrSpec{Name: "ssh_private_key_file", Type: cty.String, Required: false},
"ssh_certificate_file": &hcldec.AttrSpec{Name: "ssh_certificate_file", Type: cty.String, Required: false},
"ssh_pty": &hcldec.AttrSpec{Name: "ssh_pty", Type: cty.Bool, Required: false},
"ssh_timeout": &hcldec.AttrSpec{Name: "ssh_timeout", Type: cty.String, Required: false},
"ssh_wait_timeout": &hcldec.AttrSpec{Name: "ssh_wait_timeout", Type: cty.String, Required: false},
"ssh_agent_auth": &hcldec.AttrSpec{Name: "ssh_agent_auth", Type: cty.Bool, Required: false},
"ssh_disable_agent_forwarding": &hcldec.AttrSpec{Name: "ssh_disable_agent_forwarding", Type: cty.Bool, Required: false},
"ssh_handshake_attempts": &hcldec.AttrSpec{Name: "ssh_handshake_attempts", Type: cty.Number, Required: false},
"ssh_bastion_host": &hcldec.AttrSpec{Name: "ssh_bastion_host", Type: cty.String, Required: false},
"ssh_bastion_port": &hcldec.AttrSpec{Name: "ssh_bastion_port", Type: cty.Number, Required: false},
"ssh_bastion_agent_auth": &hcldec.AttrSpec{Name: "ssh_bastion_agent_auth", Type: cty.Bool, Required: false},
"ssh_bastion_username": &hcldec.AttrSpec{Name: "ssh_bastion_username", Type: cty.String, Required: false},
"ssh_bastion_password": &hcldec.AttrSpec{Name: "ssh_bastion_password", Type: cty.String, Required: false},
"ssh_bastion_interactive": &hcldec.AttrSpec{Name: "ssh_bastion_interactive", Type: cty.Bool, Required: false},
"ssh_bastion_private_key_file": &hcldec.AttrSpec{Name: "ssh_bastion_private_key_file", Type: cty.String, Required: false},
"ssh_bastion_certificate_file": &hcldec.AttrSpec{Name: "ssh_bastion_certificate_file", Type: cty.String, Required: false},
"ssh_file_transfer_method": &hcldec.AttrSpec{Name: "ssh_file_transfer_method", Type: cty.String, Required: false},
"ssh_proxy_host": &hcldec.AttrSpec{Name: "ssh_proxy_host", Type: cty.String, Required: false},
"ssh_proxy_port": &hcldec.AttrSpec{Name: "ssh_proxy_port", Type: cty.Number, Required: false},
"ssh_proxy_username": &hcldec.AttrSpec{Name: "ssh_proxy_username", Type: cty.String, Required: false},
"ssh_proxy_password": &hcldec.AttrSpec{Name: "ssh_proxy_password", Type: cty.String, Required: false},
"ssh_keep_alive_interval": &hcldec.AttrSpec{Name: "ssh_keep_alive_interval", Type: cty.String, Required: false},
"ssh_read_write_timeout": &hcldec.AttrSpec{Name: "ssh_read_write_timeout", Type: cty.String, Required: false},
"ssh_remote_tunnels": &hcldec.AttrSpec{Name: "ssh_remote_tunnels", Type: cty.List(cty.String), Required: false},
"ssh_local_tunnels": &hcldec.AttrSpec{Name: "ssh_local_tunnels", Type: cty.List(cty.String), Required: false},
"ssh_public_key": &hcldec.AttrSpec{Name: "ssh_public_key", Type: cty.List(cty.Number), Required: false},
"ssh_private_key": &hcldec.AttrSpec{Name: "ssh_private_key", Type: cty.List(cty.Number), Required: false},
"winrm_username": &hcldec.AttrSpec{Name: "winrm_username", Type: cty.String, Required: false},
"winrm_password": &hcldec.AttrSpec{Name: "winrm_password", Type: cty.String, Required: false},
"winrm_host": &hcldec.AttrSpec{Name: "winrm_host", Type: cty.String, Required: false},
"winrm_no_proxy": &hcldec.AttrSpec{Name: "winrm_no_proxy", Type: cty.Bool, Required: false},
"winrm_port": &hcldec.AttrSpec{Name: "winrm_port", Type: cty.Number, Required: false},
"winrm_timeout": &hcldec.AttrSpec{Name: "winrm_timeout", Type: cty.String, Required: false},
"winrm_use_ssl": &hcldec.AttrSpec{Name: "winrm_use_ssl", 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},
}
return s
}

View File

@ -1,13 +0,0 @@
package triton
import (
"testing"
)
func testConfig(t *testing.T) *Config {
return &Config{
AccessConfig: testAccessConfig(),
SourceMachineConfig: testSourceMachineConfig(t),
TargetImageConfig: testTargetImageConfig(t),
}
}

View File

@ -1,18 +0,0 @@
package triton
import (
"time"
)
type Driver interface {
GetImage(config Config) (string, error)
CreateImageFromMachine(machineId string, config Config) (string, error)
CreateMachine(config Config) (string, error)
DeleteImage(imageId string) error
DeleteMachine(machineId string) error
GetMachineIP(machineId string) (string, error)
StopMachine(machineId string) error
WaitForImageCreation(imageId string, timeout time.Duration) error
WaitForMachineDeletion(machineId string, timeout time.Duration) error
WaitForMachineState(machineId string, state string, timeout time.Duration) error
}

View File

@ -1,107 +0,0 @@
package triton
import (
"time"
)
type DriverMock struct {
CreateImageFromMachineId string
CreateImageFromMachineErr error
CreateMachineId string
CreateMachineErr error
DeleteImageId string
DeleteImageErr error
DeleteMachineId string
DeleteMachineErr error
GetImageId string
GetImageErr error
GetMachineErr error
StopMachineId string
StopMachineErr error
WaitForImageCreationErr error
WaitForMachineDeletionErr error
WaitForMachineStateErr error
}
func (d *DriverMock) GetImage(config Config) (string, error) {
if d.GetImageErr != nil {
return "", d.GetImageErr
}
return config.MachineImage, nil
}
func (d *DriverMock) CreateImageFromMachine(machineId string, config Config) (string, error) {
if d.CreateImageFromMachineErr != nil {
return "", d.CreateImageFromMachineErr
}
d.CreateImageFromMachineId = config.ImageName
return d.CreateImageFromMachineId, nil
}
func (d *DriverMock) CreateMachine(config Config) (string, error) {
if d.CreateMachineErr != nil {
return "", d.CreateMachineErr
}
d.CreateMachineId = config.MachineName
return d.CreateMachineId, nil
}
func (d *DriverMock) DeleteImage(imageId string) error {
if d.DeleteImageErr != nil {
return d.DeleteImageErr
}
d.DeleteImageId = imageId
return nil
}
func (d *DriverMock) DeleteMachine(machineId string) error {
if d.DeleteMachineErr != nil {
return d.DeleteMachineErr
}
d.DeleteMachineId = machineId
return nil
}
func (d *DriverMock) GetMachineIP(machineId string) (string, error) {
if d.GetMachineErr != nil {
return "", d.GetMachineErr
}
return "ip", nil
}
func (d *DriverMock) StopMachine(machineId string) error {
d.StopMachineId = machineId
return d.StopMachineErr
}
func (d *DriverMock) WaitForImageCreation(machineId string, timeout time.Duration) error {
return d.WaitForImageCreationErr
}
func (d *DriverMock) WaitForMachineDeletion(machineId string, timeout time.Duration) error {
return d.WaitForMachineDeletionErr
}
func (d *DriverMock) WaitForMachineState(machineId string, state string, timeout time.Duration) error {
return d.WaitForMachineStateErr
}

View File

@ -1,252 +0,0 @@
package triton
import (
"context"
"errors"
"net/http"
"sort"
"time"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
"github.com/joyent/triton-go/compute"
terrors "github.com/joyent/triton-go/errors"
)
type driverTriton struct {
client *Client
ui packersdk.Ui
}
func NewDriverTriton(ui packersdk.Ui, config Config) (Driver, error) {
client, err := config.AccessConfig.CreateTritonClient()
if err != nil {
return nil, err
}
return &driverTriton{
client: client,
ui: ui,
}, nil
}
func (d *driverTriton) GetImage(config Config) (string, error) {
computeClient, _ := d.client.Compute()
images, err := computeClient.Images().List(context.Background(), &compute.ListImagesInput{
Name: config.MachineImageFilters.Name,
OS: config.MachineImageFilters.OS,
Version: config.MachineImageFilters.Version,
Public: config.MachineImageFilters.Public,
Type: config.MachineImageFilters.Type,
State: config.MachineImageFilters.State,
Owner: config.MachineImageFilters.Owner,
})
if err != nil {
return "", err
}
if len(images) == 0 {
return "", errors.New("No images found in your search. Please refine your search criteria")
}
if len(images) > 1 {
if !config.MachineImageFilters.MostRecent {
return "", errors.New("More than 1 machine image was found in your search. Please refine your search criteria")
} else {
return mostRecentImages(images).ID, nil
}
} else {
return images[0].ID, nil
}
}
func (d *driverTriton) CreateImageFromMachine(machineId string, config Config) (string, error) {
computeClient, _ := d.client.Compute()
image, err := computeClient.Images().CreateFromMachine(context.Background(), &compute.CreateImageFromMachineInput{
MachineID: machineId,
Name: config.ImageName,
Version: config.ImageVersion,
Description: config.ImageDescription,
HomePage: config.ImageHomepage,
EULA: config.ImageEULA,
ACL: config.ImageACL,
Tags: config.ImageTags,
})
if err != nil {
return "", err
}
return image.ID, err
}
func (d *driverTriton) CreateMachine(config Config) (string, error) {
computeClient, _ := d.client.Compute()
input := &compute.CreateInstanceInput{
Package: config.MachinePackage,
Image: config.MachineImage,
Metadata: config.MachineMetadata,
Tags: config.MachineTags,
FirewallEnabled: config.MachineFirewallEnabled,
}
if config.MachineName == "" {
// If not supplied generate a name for the source VM: "packer-builder-[image_name]".
// The version is not used because it can contain characters invalid for a VM name.
input.Name = "packer-builder-" + config.ImageName
} else {
input.Name = config.MachineName
}
if len(config.MachineNetworks) > 0 {
input.Networks = config.MachineNetworks
}
machine, err := computeClient.Instances().Create(context.Background(), input)
if err != nil {
return "", err
}
return machine.ID, nil
}
func (d *driverTriton) DeleteImage(imageId string) error {
computeClient, _ := d.client.Compute()
return computeClient.Images().Delete(context.Background(), &compute.DeleteImageInput{
ImageID: imageId,
})
}
func (d *driverTriton) DeleteMachine(machineId string) error {
computeClient, _ := d.client.Compute()
return computeClient.Instances().Delete(context.Background(), &compute.DeleteInstanceInput{
ID: machineId,
})
}
func (d *driverTriton) GetMachineIP(machineId string) (string, error) {
computeClient, _ := d.client.Compute()
machine, err := computeClient.Instances().Get(context.Background(), &compute.GetInstanceInput{
ID: machineId,
})
if err != nil {
return "", err
}
return machine.PrimaryIP, nil
}
func (d *driverTriton) StopMachine(machineId string) error {
computeClient, _ := d.client.Compute()
return computeClient.Instances().Stop(context.Background(), &compute.StopInstanceInput{
InstanceID: machineId,
})
}
// waitForMachineState uses the supplied client to wait for the state of
// the machine with the given ID to reach the state described in state.
// If timeout is reached before the machine reaches the required state, an
// error is returned. If the machine reaches the target state within the
// timeout, nil is returned.
func (d *driverTriton) WaitForMachineState(machineId string, state string, timeout time.Duration) error {
return waitFor(
func() (bool, error) {
computeClient, _ := d.client.Compute()
machine, err := computeClient.Instances().Get(context.Background(), &compute.GetInstanceInput{
ID: machineId,
})
if machine == nil {
return false, err
}
return machine.State == state, err
},
3*time.Second,
timeout,
)
}
// waitForMachineDeletion uses the supplied client to wait for the machine
// with the given ID to be deleted. It is expected that the API call to delete
// the machine has already been issued at this point.
func (d *driverTriton) WaitForMachineDeletion(machineId string, timeout time.Duration) error {
return waitFor(
func() (bool, error) {
computeClient, _ := d.client.Compute()
_, err := computeClient.Instances().Get(context.Background(), &compute.GetInstanceInput{
ID: machineId,
})
if err != nil {
// Return true only when we receive a 410 (Gone) response. A 404
// indicates that the machine is being deleted whereas a 410 indicates
// that this process has completed.
if terrors.IsSpecificStatusCode(err, http.StatusGone) {
return true, nil
}
}
return false, err
},
3*time.Second,
timeout,
)
}
func (d *driverTriton) WaitForImageCreation(imageId string, timeout time.Duration) error {
return waitFor(
func() (bool, error) {
computeClient, _ := d.client.Compute()
image, err := computeClient.Images().Get(context.Background(), &compute.GetImageInput{
ImageID: imageId,
})
if image == nil {
return false, err
}
return image.State == "active", err
},
3*time.Second,
timeout,
)
}
func waitFor(f func() (bool, error), every, timeout time.Duration) error {
start := time.Now()
for time.Since(start) <= timeout {
stop, err := f()
if err != nil {
return err
}
if stop {
return nil
}
time.Sleep(every)
}
return errors.New("Timed out while waiting for resource change")
}
func mostRecentImages(images []*compute.Image) *compute.Image {
return sortImages(images)[0]
}
type imageSort []*compute.Image
func sortImages(images []*compute.Image) []*compute.Image {
sortedImages := images
sort.Sort(sort.Reverse(imageSort(sortedImages)))
return sortedImages
}
func (a imageSort) Len() int {
return len(a)
}
func (a imageSort) Swap(i, j int) {
a[i], a[j] = a[j], a[i]
}
func (a imageSort) Less(i, j int) bool {
itime := a[i].PublishedAt
jtime := a[j].PublishedAt
return itime.Unix() < jtime.Unix()
}

View File

@ -1,118 +0,0 @@
//go:generate packer-sdc struct-markdown
//go:generate packer-sdc mapstructure-to-hcl2 -type MachineImageFilter
package triton
import (
"fmt"
"github.com/hashicorp/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
)
// SourceMachineConfig represents the configuration to run a machine using
// the SDC API in order for provisioning to take place.
type SourceMachineConfig struct {
// Name of the VM used for building the
// image. Does not affect (and does not have to be the same) as the name for a
// VM instance running this image. Maximum 512 characters but should in
// practice be much shorter (think between 5 and 20 characters). For example
// mysql-64-server-image-builder. When omitted defaults to
// packer-builder-[image_name].
MachineName string `mapstructure:"source_machine_name" required:"false"`
// The Triton package to use while
// building the image. Does not affect (and does not have to be the same) as
// the package which will be used for a VM instance running this image. On the
// Joyent public cloud this could for example be g3-standard-0.5-smartos.
MachinePackage string `mapstructure:"source_machine_package" required:"true"`
// The UUID of the image to base the new
// image on. Triton supports multiple types of images, called 'brands' in
// Triton / Joyent lingo, for contains and VM's. See the chapter Containers
// and virtual machines in
// the Joyent Triton documentation for detailed information. The following
// brands are currently supported by this builder:joyent andkvm. The
// choice of base image automatically decides the brand. On the Joyent public
// cloud a valid source_machine_image could for example be
// 70e3ae72-96b6-11e6-9056-9737fd4d0764 for version 16.3.1 of the 64bit
// SmartOS base image (a 'joyent' brand image). source_machine_image_filter
// can be used to populate this UUID.
MachineImage string `mapstructure:"source_machine_image" required:"true"`
// The UUID's of Triton
// networks added to the source machine used for creating the image. For
// example if any of the provisioners which are run need Internet access you
// will need to add the UUID's of the appropriate networks here. If this is
// not specified, instances will be placed into the default Triton public and
// internal networks.
MachineNetworks []string `mapstructure:"source_machine_networks" required:"false"`
// Triton metadata
// applied to the VM used to create the image. Metadata can be used to pass
// configuration information to the VM without the need for networking. See
// Using the metadata
// API in the
// Joyent documentation for more information. This can for example be used to
// set the user-script metadata key to have Triton start a user supplied
// script after the VM has booted.
MachineMetadata map[string]string `mapstructure:"source_machine_metadata" required:"false"`
// Key/value pair tags applied to the VM used to create the image.
MachineTags map[string]string `mapstructure:"source_machine_tags" required:"false"`
// Same as [`source_machine_tags`](#source_machine_tags) but defined as a
// singular block containing a `key` and a `value` field. In HCL2 mode the
// [`dynamic_block`](/docs/templates/hcl_templates/expressions#dynamic-blocks)
// will allow you to create those programatically.
MachineTag config.KeyValues `mapstructure:"source_machine_tag" required:"false"`
// Whether or not the firewall
// of the VM used to create an image of is enabled. The Triton firewall only
// filters inbound traffic to the VM. All outbound traffic is always allowed.
// Currently this builder does not provide an interface to add specific
// firewall rules. Unless you have a global rule defined in Triton which
// allows SSH traffic enabling the firewall will interfere with the SSH
// provisioner. The default is false.
MachineFirewallEnabled bool `mapstructure:"source_machine_firewall_enabled" required:"false"`
// Filters used to populate the
// source_machine_image field. Example:
MachineImageFilters MachineImageFilter `mapstructure:"source_machine_image_filter" required:"false"`
}
type MachineImageFilter struct {
MostRecent bool `mapstructure:"most_recent"`
Name string
OS string
Version string
Public bool
State string
Owner string
Type string
}
func (m *MachineImageFilter) Empty() bool {
return m.Name == "" && m.OS == "" && m.Version == "" && m.State == "" && m.Owner == "" && m.Type == ""
}
// Prepare performs basic validation on a SourceMachineConfig struct.
func (c *SourceMachineConfig) Prepare(ctx *interpolate.Context) []error {
var errs []error
if c.MachinePackage == "" {
errs = append(errs, fmt.Errorf("A source_machine_package must be specified"))
}
if c.MachineImage != "" && c.MachineImageFilters.Name != "" {
errs = append(errs, fmt.Errorf("You cannot specify a Machine Image and also Machine Name filter"))
}
if c.MachineNetworks == nil {
c.MachineNetworks = []string{}
}
if c.MachineMetadata == nil {
c.MachineMetadata = make(map[string]string)
}
if c.MachineTags == nil {
c.MachineTags = make(map[string]string)
}
errs = append(errs, c.MachineTag.CopyOn(&c.MachineTags)...)
return errs
}

View File

@ -1,45 +0,0 @@
// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT.
package triton
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/zclconf/go-cty/cty"
)
// FlatMachineImageFilter is an auto-generated flat version of MachineImageFilter.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatMachineImageFilter struct {
MostRecent *bool `mapstructure:"most_recent" cty:"most_recent" hcl:"most_recent"`
Name *string `cty:"name" hcl:"name"`
OS *string `cty:"os" hcl:"os"`
Version *string `cty:"version" hcl:"version"`
Public *bool `cty:"public" hcl:"public"`
State *string `cty:"state" hcl:"state"`
Owner *string `cty:"owner" hcl:"owner"`
Type *string `cty:"type" hcl:"type"`
}
// FlatMapstructure returns a new FlatMachineImageFilter.
// FlatMachineImageFilter is an auto-generated flat version of MachineImageFilter.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*MachineImageFilter) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatMachineImageFilter)
}
// HCL2Spec returns the hcl spec of a MachineImageFilter.
// This spec is used by HCL to read the fields of MachineImageFilter.
// The decoded values from this spec will then be applied to a FlatMachineImageFilter.
func (*FlatMachineImageFilter) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"most_recent": &hcldec.AttrSpec{Name: "most_recent", Type: cty.Bool, Required: false},
"name": &hcldec.AttrSpec{Name: "name", Type: cty.String, Required: false},
"os": &hcldec.AttrSpec{Name: "os", Type: cty.String, Required: false},
"version": &hcldec.AttrSpec{Name: "version", Type: cty.String, Required: false},
"public": &hcldec.AttrSpec{Name: "public", Type: cty.Bool, Required: false},
"state": &hcldec.AttrSpec{Name: "state", Type: cty.String, Required: false},
"owner": &hcldec.AttrSpec{Name: "owner", Type: cty.String, Required: false},
"type": &hcldec.AttrSpec{Name: "type", Type: cty.String, Required: false},
}
return s
}

View File

@ -1,50 +0,0 @@
package triton
import (
"testing"
)
func TestSourceMachineConfig_Prepare(t *testing.T) {
sc := testSourceMachineConfig(t)
errs := sc.Prepare(nil)
if errs != nil {
t.Fatalf("should not error: %#v", sc)
}
sc = testSourceMachineConfig(t)
sc.MachineName = ""
errs = sc.Prepare(nil)
if errs != nil {
t.Fatalf("should not error: %#v", sc)
}
sc = testSourceMachineConfig(t)
sc.MachinePackage = ""
errs = sc.Prepare(nil)
if errs == nil {
t.Fatalf("should error: %#v", sc)
}
}
func testSourceMachineConfig(t *testing.T) SourceMachineConfig {
return SourceMachineConfig{
MachineName: "test-machine",
MachinePackage: "test-package",
MachineImage: "test-image",
MachineNetworks: []string{
"test-network-1",
"test-network-2",
},
MachineMetadata: map[string]string{
"test-metadata-key1": "test-metadata-value1",
"test-metadata-key2": "test-metadata-value2",
"test-metadata-key3": "test-metadata-value3",
},
MachineTags: map[string]string{
"test-tags-key1": "test-tags-value1",
"test-tags-key2": "test-tags-value2",
"test-tags-key3": "test-tags-value3",
},
MachineFirewallEnabled: false,
}
}

View File

@ -1,26 +0,0 @@
package triton
import (
"log"
"github.com/hashicorp/packer-plugin-sdk/multistep"
)
func commHost(host string) func(multistep.StateBag) (string, error) {
return func(state multistep.StateBag) (string, error) {
if host != "" {
log.Printf("Using host value: %s", host)
return host, nil
}
driver := state.Get("driver").(Driver)
machineID := state.Get("machine").(string)
machine, err := driver.GetMachineIP(machineID)
if err != nil {
return "", err
}
return machine, nil
}
}

View File

@ -1,46 +0,0 @@
package triton
import (
"context"
"fmt"
"time"
"github.com/hashicorp/packer-plugin-sdk/multistep"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
// StepCreateImageFromMachine creates an image with the specified attributes
// from the machine with the given ID, and waits for the image to be created.
// The machine must be in the "stopped" state prior to this step being run.
type StepCreateImageFromMachine struct{}
func (s *StepCreateImageFromMachine) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packersdk.Ui)
machineId := state.Get("machine").(string)
ui.Say("Creating image from source machine...")
imageId, err := driver.CreateImageFromMachine(machineId, *config)
if err != nil {
state.Put("error", fmt.Errorf("Problem creating image from machine: %s", err))
return multistep.ActionHalt
}
ui.Say("Waiting for image to become available...")
err = driver.WaitForImageCreation(imageId, 10*time.Minute)
if err != nil {
state.Put("error", fmt.Errorf("Problem waiting for image to become available: %s", err))
return multistep.ActionHalt
}
state.Put("image", imageId)
return multistep.ActionContinue
}
func (s *StepCreateImageFromMachine) Cleanup(state multistep.StateBag) {
// No cleanup
}

View File

@ -1,74 +0,0 @@
package triton
import (
"context"
"errors"
"testing"
"github.com/hashicorp/packer-plugin-sdk/multistep"
)
func TestStepCreateImageFromMachine(t *testing.T) {
state := testState(t)
step := new(StepCreateImageFromMachine)
defer step.Cleanup(state)
state.Put("machine", "test-machine-id")
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
_, ok := state.GetOk("image")
if !ok {
t.Fatalf("should have image")
}
step.Cleanup(state)
}
func TestStepCreateImageFromMachine_CreateImageFromMachineError(t *testing.T) {
state := testState(t)
step := new(StepCreateImageFromMachine)
defer step.Cleanup(state)
driver := state.Get("driver").(*DriverMock)
state.Put("machine", "test-machine-id")
driver.CreateImageFromMachineErr = errors.New("error")
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); !ok {
t.Fatalf("should have error")
}
if _, ok := state.GetOk("image"); ok {
t.Fatalf("should NOT have image")
}
}
func TestStepCreateImageFromMachine_WaitForImageCreationError(t *testing.T) {
state := testState(t)
step := new(StepCreateImageFromMachine)
defer step.Cleanup(state)
driver := state.Get("driver").(*DriverMock)
state.Put("machine", "test-machine-id")
driver.WaitForImageCreationErr = errors.New("error")
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); !ok {
t.Fatalf("should have error")
}
if _, ok := state.GetOk("image"); ok {
t.Fatalf("should NOT have image")
}
}

View File

@ -1,87 +0,0 @@
package triton
import (
"context"
"fmt"
"time"
"github.com/hashicorp/packer-plugin-sdk/multistep"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
// StepCreateSourceMachine creates an machine with the specified attributes
// and waits for it to become available for provisioners.
type StepCreateSourceMachine struct{}
func (s *StepCreateSourceMachine) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packersdk.Ui)
if !config.MachineImageFilters.Empty() {
ui.Say("Selecting an image based on search criteria")
imageId, err := driver.GetImage(*config)
if err != nil {
state.Put("error", fmt.Errorf("Problem selecting an image based on an search criteria: %s", err))
return multistep.ActionHalt
}
ui.Say(fmt.Sprintf("Based, on given search criteria, Machine ID is: %q", imageId))
config.MachineImage = imageId
}
machineId, err := driver.CreateMachine(*config)
if err != nil {
state.Put("error", fmt.Errorf("Problem creating source machine: %s", err))
return multistep.ActionHalt
}
ui.Say("Waiting for source machine to become available...")
err = driver.WaitForMachineState(machineId, "running", 10*time.Minute)
if err != nil {
state.Put("error", fmt.Errorf("Problem waiting for source machine to become available: %s", err))
return multistep.ActionHalt
}
state.Put("machine", machineId)
// instance_id is the generic term used so that users can have access to the
// instance id inside of the provisioners, used in step_provision.
state.Put("instance_id", machineId)
return multistep.ActionContinue
}
func (s *StepCreateSourceMachine) Cleanup(state multistep.StateBag) {
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packersdk.Ui)
machineIdRaw, ok := state.GetOk("machine")
if ok && machineIdRaw.(string) != "" {
machineId := machineIdRaw.(string)
ui.Say(fmt.Sprintf("Stopping source machine (%s)...", machineId))
err := driver.StopMachine(machineId)
if err != nil {
state.Put("error", fmt.Errorf("Problem stopping source machine: %s", err))
return
}
ui.Say(fmt.Sprintf("Waiting for source machine to stop (%s)...", machineId))
err = driver.WaitForMachineState(machineId, "stopped", 10*time.Minute)
if err != nil {
state.Put("error", fmt.Errorf("Problem waiting for source machine to stop: %s", err))
return
}
ui.Say(fmt.Sprintf("Deleting source machine (%s)...", machineId))
err = driver.DeleteMachine(machineId)
if err != nil {
state.Put("error", fmt.Errorf("Problem deleting source machine: %s", err))
return
}
ui.Say(fmt.Sprintf("Waiting for source machine to be destroyed (%s)...", machineId))
err = driver.WaitForMachineDeletion(machineId, 10*time.Minute)
if err != nil {
state.Put("error", fmt.Errorf("Problem waiting for source machine to be deleted: %s", err))
return
}
}
}

View File

@ -1,160 +0,0 @@
package triton
import (
"context"
"errors"
"testing"
"github.com/hashicorp/packer-plugin-sdk/multistep"
)
func TestStepCreateSourceMachine(t *testing.T) {
state := testState(t)
step := new(StepCreateSourceMachine)
defer step.Cleanup(state)
driver := state.Get("driver").(*DriverMock)
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
machineIdRaw, ok := state.GetOk("machine")
if !ok {
t.Fatalf("should have machine")
}
step.Cleanup(state)
if driver.DeleteMachineId != machineIdRaw.(string) {
t.Fatalf("should've deleted machine (%s != %s)", driver.DeleteMachineId, machineIdRaw.(string))
}
}
func TestStepCreateSourceMachine_CreateMachineError(t *testing.T) {
state := testState(t)
step := new(StepCreateSourceMachine)
defer step.Cleanup(state)
driver := state.Get("driver").(*DriverMock)
driver.CreateMachineErr = errors.New("error")
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); !ok {
t.Fatalf("should have error")
}
if _, ok := state.GetOk("machine"); ok {
t.Fatalf("should NOT have machine")
}
}
func TestStepCreateSourceMachine_WaitForMachineStateError(t *testing.T) {
state := testState(t)
step := new(StepCreateSourceMachine)
defer step.Cleanup(state)
driver := state.Get("driver").(*DriverMock)
driver.WaitForMachineStateErr = errors.New("error")
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); !ok {
t.Fatalf("should have error")
}
if _, ok := state.GetOk("machine"); ok {
t.Fatalf("should NOT have machine")
}
}
func TestStepCreateSourceMachine_StopMachineError(t *testing.T) {
state := testState(t)
step := new(StepCreateSourceMachine)
defer step.Cleanup(state)
driver := state.Get("driver").(*DriverMock)
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
_, ok := state.GetOk("machine")
if !ok {
t.Fatalf("should have machine")
}
driver.StopMachineErr = errors.New("error")
step.Cleanup(state)
if _, ok := state.GetOk("error"); !ok {
t.Fatalf("should have error")
}
if _, ok := state.GetOk("machine"); !ok {
t.Fatalf("should have machine")
}
}
func TestStepCreateSourceMachine_WaitForMachineStoppedError(t *testing.T) {
state := testState(t)
step := new(StepCreateSourceMachine)
defer step.Cleanup(state)
driver := state.Get("driver").(*DriverMock)
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
_, ok := state.GetOk("machine")
if !ok {
t.Fatalf("should have machine")
}
driver.WaitForMachineStateErr = errors.New("error")
step.Cleanup(state)
if _, ok := state.GetOk("error"); !ok {
t.Fatalf("should have error")
}
if _, ok := state.GetOk("machine"); !ok {
t.Fatalf("should have machine")
}
}
func TestStepCreateSourceMachine_DeleteMachineError(t *testing.T) {
state := testState(t)
step := new(StepCreateSourceMachine)
defer step.Cleanup(state)
driver := state.Get("driver").(*DriverMock)
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
_, ok := state.GetOk("machine")
if !ok {
t.Fatalf("should have machine")
}
driver.DeleteMachineErr = errors.New("error")
step.Cleanup(state)
if _, ok := state.GetOk("error"); !ok {
t.Fatalf("should have error")
}
if _, ok := state.GetOk("machine"); !ok {
t.Fatalf("should have machine")
}
}

View File

@ -1,42 +0,0 @@
package triton
import (
"context"
"fmt"
"time"
"github.com/hashicorp/packer-plugin-sdk/multistep"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
// StepDeleteMachine deletes the machine with the ID specified in state["machine"]
type StepDeleteMachine struct{}
func (s *StepDeleteMachine) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packersdk.Ui)
machineId := state.Get("machine").(string)
ui.Say("Deleting source machine...")
err := driver.DeleteMachine(machineId)
if err != nil {
state.Put("error", fmt.Errorf("Problem deleting source machine: %s", err))
return multistep.ActionHalt
}
ui.Say("Waiting for source machine to be deleted...")
err = driver.WaitForMachineDeletion(machineId, 10*time.Minute)
if err != nil {
state.Put("error", fmt.Errorf("Problem waiting for source machine to be deleted: %s", err))
return multistep.ActionHalt
}
state.Put("machine", "")
return multistep.ActionContinue
}
func (s *StepDeleteMachine) Cleanup(state multistep.StateBag) {
// No clean up to do here...
}

View File

@ -1,80 +0,0 @@
package triton
import (
"context"
"errors"
"testing"
"github.com/hashicorp/packer-plugin-sdk/multistep"
)
func TestStepDeleteMachine(t *testing.T) {
state := testState(t)
step := new(StepDeleteMachine)
defer step.Cleanup(state)
driver := state.Get("driver").(*DriverMock)
machineId := "test-machine-id"
state.Put("machine", machineId)
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
step.Cleanup(state)
if driver.DeleteMachineId != machineId {
t.Fatalf("should've deleted machine (%s != %s)", driver.DeleteMachineId, machineId)
}
}
func TestStepDeleteMachine_DeleteMachineError(t *testing.T) {
state := testState(t)
step := new(StepDeleteMachine)
defer step.Cleanup(state)
driver := state.Get("driver").(*DriverMock)
machineId := "test-machine-id"
state.Put("machine", machineId)
driver.DeleteMachineErr = errors.New("error")
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); !ok {
t.Fatalf("should have error")
}
if _, ok := state.GetOk("machine"); !ok {
t.Fatalf("should have machine")
}
}
func TestStepDeleteMachine_WaitForMachineDeletionError(t *testing.T) {
state := testState(t)
step := new(StepDeleteMachine)
defer step.Cleanup(state)
driver := state.Get("driver").(*DriverMock)
machineId := "test-machine-id"
state.Put("machine", machineId)
driver.WaitForMachineDeletionErr = errors.New("error")
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); !ok {
t.Fatalf("should have error")
}
if _, ok := state.GetOk("machine"); !ok {
t.Fatalf("should have machine")
}
}

View File

@ -1,42 +0,0 @@
package triton
import (
"context"
"fmt"
"time"
"github.com/hashicorp/packer-plugin-sdk/multistep"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
// StepStopMachine stops the machine with the given Machine ID, and waits
// for it to reach the stopped state.
type StepStopMachine struct{}
func (s *StepStopMachine) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packersdk.Ui)
machineId := state.Get("machine").(string)
ui.Say(fmt.Sprintf("Stopping source machine (%s)...", machineId))
err := driver.StopMachine(machineId)
if err != nil {
state.Put("error", fmt.Errorf("Problem stopping source machine: %s", err))
return multistep.ActionHalt
}
ui.Say(fmt.Sprintf("Waiting for source machine to stop (%s)...", machineId))
err = driver.WaitForMachineState(machineId, "stopped", 10*time.Minute)
if err != nil {
state.Put("error", fmt.Errorf("Problem waiting for source machine to stop: %s", err))
return multistep.ActionHalt
}
return multistep.ActionContinue
}
func (s *StepStopMachine) Cleanup(state multistep.StateBag) {
// Explicitly don't clean up here as StepCreateSourceMachine will do it if necessary
// and there is no real meaning to cleaning this up.
}

View File

@ -1,72 +0,0 @@
package triton
import (
"context"
"errors"
"testing"
"github.com/hashicorp/packer-plugin-sdk/multistep"
)
func TestStepStopMachine(t *testing.T) {
state := testState(t)
step := new(StepStopMachine)
defer step.Cleanup(state)
driver := state.Get("driver").(*DriverMock)
machineId := "test-machine-id"
state.Put("machine", machineId)
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
step.Cleanup(state)
if driver.StopMachineId != machineId {
t.Fatalf("should've stopped machine (%s != %s)", driver.StopMachineId, machineId)
}
}
func TestStepStopMachine_StopMachineError(t *testing.T) {
state := testState(t)
step := new(StepStopMachine)
defer step.Cleanup(state)
driver := state.Get("driver").(*DriverMock)
machineId := "test-machine-id"
state.Put("machine", machineId)
driver.StopMachineErr = errors.New("error")
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); !ok {
t.Fatalf("should have error")
}
}
func TestStepStopMachine_WaitForMachineStoppedError(t *testing.T) {
state := testState(t)
step := new(StepStopMachine)
defer step.Cleanup(state)
driver := state.Get("driver").(*DriverMock)
machineId := "test-machine-id"
state.Put("machine", machineId)
driver.WaitForMachineStateErr = errors.New("error")
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); !ok {
t.Fatalf("should have error")
}
}

View File

@ -1,21 +0,0 @@
package triton
import (
"bytes"
"testing"
"github.com/hashicorp/packer-plugin-sdk/multistep"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
func testState(t *testing.T) multistep.StateBag {
state := new(multistep.BasicStateBag)
state.Put("config", testConfig(t))
state.Put("driver", &DriverMock{})
state.Put("hook", &packersdk.MockHook{})
state.Put("ui", &packersdk.BasicUi{
Reader: new(bytes.Buffer),
Writer: new(bytes.Buffer),
})
return state
}

View File

@ -1,25 +0,0 @@
package triton
import (
"context"
"time"
"github.com/hashicorp/packer-plugin-sdk/multistep"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
)
// StepWaitForStopNotToFail waits for 10 seconds before returning with continue
// in order to prevent an observed issue where machines stopped immediately after
// they are started never actually stop.
type StepWaitForStopNotToFail struct{}
func (s *StepWaitForStopNotToFail) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packersdk.Ui)
ui.Say("Waiting 10 seconds to avoid potential SDC bug...")
time.Sleep(10 * time.Second)
return multistep.ActionContinue
}
func (s *StepWaitForStopNotToFail) Cleanup(state multistep.StateBag) {
// No clean up required...
}

View File

@ -1,66 +0,0 @@
//go:generate packer-sdc struct-markdown
package triton
import (
"fmt"
"github.com/hashicorp/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
)
// TargetImageConfig represents the configuration for the image to be created
// from the source machine.
type TargetImageConfig struct {
// The name the finished image in Triton will be
// assigned. Maximum 512 characters but should in practice be much shorter
// (think between 5 and 20 characters). For example postgresql-95-server for
// an image used as a PostgreSQL 9.5 server.
ImageName string `mapstructure:"image_name" required:"true"`
// The version string for this image. Maximum 128
// characters. Any string will do but a format of Major.Minor.Patch is
// strongly advised by Joyent. See Semantic Versioning
// for more information on the Major.Minor.Patch versioning format.
ImageVersion string `mapstructure:"image_version" required:"true"`
// Description of the image. Maximum 512
// characters.
ImageDescription string `mapstructure:"image_description" required:"false"`
// URL of the homepage where users can find
// information about the image. Maximum 128 characters.
ImageHomepage string `mapstructure:"image_homepage" required:"false"`
// URL of the End User License Agreement (EULA)
// for the image. Maximum 128 characters.
ImageEULA string `mapstructure:"image_eula_url" required:"false"`
// The UUID's of the users which will have
// access to this image. When omitted only the owner (the Triton user whose
// credentials are used) will have access to the image.
ImageACL []string `mapstructure:"image_acls" required:"false"`
// Name/Value tags applied to the image.
ImageTags map[string]string `mapstructure:"image_tags" required:"false"`
// Same as [`image_tags`](#image_tags) but defined as a singular repeatable
// block containing a `name` and a `value` field. In HCL2 mode the
// [`dynamic_block`](/docs/templates/hcl_templates/expressions#dynamic-blocks)
// will allow you to create those programatically.
ImageTag config.NameValues `mapstructure:"image_tag" required:"false"`
}
// Prepare performs basic validation on a TargetImageConfig struct.
func (c *TargetImageConfig) Prepare(ctx *interpolate.Context) []error {
var errs []error
errs = append(errs, c.ImageTag.CopyOn(&c.ImageTags)...)
if c.ImageName == "" {
errs = append(errs, fmt.Errorf("An image_name must be specified"))
}
if c.ImageVersion == "" {
errs = append(errs, fmt.Errorf("An image_version must be specified"))
}
if len(errs) > 0 {
return errs
}
return nil
}

View File

@ -1,46 +0,0 @@
package triton
import (
"testing"
)
func TestTargetImageConfig_Prepare(t *testing.T) {
tic := testTargetImageConfig(t)
errs := tic.Prepare(nil)
if errs != nil {
t.Fatalf("should not error: %#v", tic)
}
tic = testTargetImageConfig(t)
tic.ImageName = ""
errs = tic.Prepare(nil)
if errs == nil {
t.Fatalf("should error: %#v", tic)
}
tic = testTargetImageConfig(t)
tic.ImageVersion = ""
errs = tic.Prepare(nil)
if errs == nil {
t.Fatalf("should error: %#v", tic)
}
}
func testTargetImageConfig(t *testing.T) TargetImageConfig {
return TargetImageConfig{
ImageName: "test-image",
ImageVersion: "test-version",
ImageDescription: "test-description",
ImageHomepage: "test-homepage",
ImageEULA: "test-eula",
ImageACL: []string{
"test-acl-1",
"test-acl-2",
},
ImageTags: map[string]string{
"test-tags-key1": "test-tags-value1",
"test-tags-key2": "test-tags-value2",
"test-tags-key3": "test-tags-value3",
},
}
}

View File

@ -1,13 +0,0 @@
package version
import (
"github.com/hashicorp/packer-plugin-sdk/version"
packerVersion "github.com/hashicorp/packer/version"
)
var TritonPluginVersion *version.PluginVersion
func init() {
TritonPluginVersion = version.InitializePluginVersion(
packerVersion.Version, packerVersion.VersionPrerelease)
}

View File

@ -24,7 +24,6 @@ import (
oneandonebuilder "github.com/hashicorp/packer/builder/oneandone"
profitbricksbuilder "github.com/hashicorp/packer/builder/profitbricks"
tencentcloudcvmbuilder "github.com/hashicorp/packer/builder/tencentcloud/cvm"
tritonbuilder "github.com/hashicorp/packer/builder/triton"
yandexbuilder "github.com/hashicorp/packer/builder/yandex"
artificepostprocessor "github.com/hashicorp/packer/post-processor/artifice"
checksumpostprocessor "github.com/hashicorp/packer/post-processor/checksum"
@ -62,7 +61,6 @@ var Builders = map[string]packersdk.Builder{
"oneandone": new(oneandonebuilder.Builder),
"profitbricks": new(profitbricksbuilder.Builder),
"tencentcloud-cvm": new(tencentcloudcvmbuilder.Builder),
"triton": new(tritonbuilder.Builder),
"yandex": new(yandexbuilder.Builder),
}

View File

@ -54,6 +54,7 @@ import (
puppetserverprovisioner "github.com/hashicorp/packer-plugin-puppet/provisioner/puppet-server"
qemubuilder "github.com/hashicorp/packer-plugin-qemu/builder/qemu"
scalewaybuilder "github.com/hashicorp/packer-plugin-scaleway/builder/scaleway"
tritonbuilder "github.com/hashicorp/packer-plugin-triton/builder/triton"
uclouduhostbuilder "github.com/hashicorp/packer-plugin-ucloud/builder/ucloud/uhost"
ucloudimportpostprocessor "github.com/hashicorp/packer-plugin-ucloud/post-processor/ucloud-import"
vagrantbuilder "github.com/hashicorp/packer-plugin-vagrant/builder/vagrant"
@ -106,6 +107,7 @@ var VendoredBuilders = map[string]packersdk.Builder{
"parallels-pvm": new(parallelspvmbuilder.Builder),
"qemu": new(qemubuilder.Builder),
"scaleway": new(scalewaybuilder.Builder),
"triton": new(tritonbuilder.Builder),
"ucloud-uhost": new(uclouduhostbuilder.Builder),
"vagrant": new(vagrantbuilder.Builder),
"vsphere-clone": new(vsphereclonebuilder.Builder),

10
go.mod
View File

@ -16,10 +16,8 @@ require (
github.com/cheggaaa/pb v1.0.27
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/digitalocean/godo v1.60.0
github.com/dsnet/compress v0.0.1
github.com/exoscale/packer-plugin-exoscale v0.1.1
github.com/go-ini/ini v1.62.0
github.com/go-resty/resty/v2 v2.3.0
github.com/gobwas/glob v0.2.3
github.com/google/go-cmp v0.5.5
@ -27,13 +25,10 @@ require (
github.com/google/uuid v1.2.0
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0
github.com/hako/durafmt v0.0.0-20200710122514-c0fb7b4da026
github.com/hashicorp/errwrap v1.0.0
github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/hashicorp/go-cty-funcs v0.0.0-20200930094925-2721b1e36840
github.com/hashicorp/go-getter/v2 v2.0.0-20200604122502-a6995fa1edad
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/go-oracle-terraform v0.17.0
github.com/hashicorp/go-uuid v1.0.2
github.com/hashicorp/go-version v1.3.0
github.com/hashicorp/hcl/v2 v2.10.0
@ -52,7 +47,7 @@ require (
github.com/hashicorp/packer-plugin-linode v0.0.2
github.com/hashicorp/packer-plugin-ncloud v0.0.2
github.com/hashicorp/packer-plugin-openstack v0.0.2
github.com/hashicorp/packer-plugin-oracle v0.0.3 // indirect
github.com/hashicorp/packer-plugin-oracle v0.0.3
github.com/hashicorp/packer-plugin-outscale v0.0.1
github.com/hashicorp/packer-plugin-parallels v0.0.1
github.com/hashicorp/packer-plugin-proxmox v0.0.2
@ -60,13 +55,13 @@ require (
github.com/hashicorp/packer-plugin-qemu v0.0.1
github.com/hashicorp/packer-plugin-scaleway v0.0.1
github.com/hashicorp/packer-plugin-sdk v0.2.0
github.com/hashicorp/packer-plugin-triton v0.0.0-20210421085122-768dd7c764d9
github.com/hashicorp/packer-plugin-ucloud v0.0.1
github.com/hashicorp/packer-plugin-vagrant v0.0.3
github.com/hashicorp/packer-plugin-virtualbox v0.0.1
github.com/hashicorp/packer-plugin-vmware v0.0.1
github.com/hashicorp/packer-plugin-vsphere v0.0.1
github.com/hetznercloud/hcloud-go v1.15.1
github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62
github.com/klauspost/pgzip v0.0.0-20151221113845-47f36e165cec
github.com/masterzen/winrm v0.0.0-20201030141608-56ca5c5f2380
github.com/mattn/go-tty v0.0.0-20191112051231-74040eebce08
@ -76,7 +71,6 @@ require (
github.com/mitchellh/panicwrap v1.0.0
github.com/mitchellh/prefixedio v0.0.0-20151214002211-6e6954073784
github.com/mitchellh/reflectwalk v1.0.0
github.com/oracle/oci-go-sdk/v36 v36.2.0
github.com/pierrec/lz4 v2.0.5+incompatible
github.com/pkg/errors v0.9.1
github.com/posener/complete v1.2.3

93
go.sum
View File

@ -87,6 +87,7 @@ github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb0
github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.1.0/go.mod h1:P+3VS0ETiQPyWOx3vB/oeC8J3qd7jnVZLYAFwWgGRt8=
github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.2.0 h1:c7GgSBfMt51UGM4SI1F7IFOokOVZO+uxNcJL3Xsmkp4=
github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.2.0/go.mod h1:P+3VS0ETiQPyWOx3vB/oeC8J3qd7jnVZLYAFwWgGRt8=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
@ -100,6 +101,8 @@ github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KM
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw=
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190418113227-25233c783f4e/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA=
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1028 h1:lBif3zUMR6sjgfONVqfnjjjdXIK09S4Lvkze20ApE8w=
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1028/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA=
@ -126,6 +129,7 @@ github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkE
github.com/approvals/go-approval-tests v0.0.0-20160714161514-ad96e53bea43 h1:ePCAQPf5tUc5IMcUvu6euhSGna7jzs7eiXtJXHig6Zc=
github.com/approvals/go-approval-tests v0.0.0-20160714161514-ad96e53bea43/go.mod h1:S6puKjZ9ZeqUPBv2hEBnMZGcM2J6mOsDRQcmxkMAND0=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM=
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=
@ -168,6 +172,7 @@ github.com/aws/smithy-go v1.2.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAm
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
@ -179,6 +184,7 @@ github.com/bmatcuk/doublestar v1.1.5/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee h1:BnPxIde0gjtTnc9Er7cxvBk8DHLWhEux0SxayC8dP6I=
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cheggaaa/pb v1.0.27 h1:wIkZHkNfC7R6GI5w7l/PdAdzXzlrbcI3p8OAlnkTsnc=
github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
@ -193,6 +199,14 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -203,6 +217,7 @@ github.com/deepmap/oapi-codegen v1.5.1 h1:Xx8/OynzWhQeKFWr182hg6Ja2evS1gcqdja7qM
github.com/deepmap/oapi-codegen v1.5.1/go.mod h1:Eb1vtV3f58zvm37CJV4UAQ1bECb0fgAVvTdonC1ftJg=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/digitalocean/go-libvirt v0.0.0-20190626172931-4d226dd6c437/go.mod h1:PRcPVAAma6zcLpFd4GZrjR/MRpood3TamjKI2m/z/Uw=
github.com/digitalocean/go-libvirt v0.0.0-20201209184759-e2a69bcd5bd1/go.mod h1:QS1XzqZLcDniNYrN7EZefq3wIyb/M2WmJbql4ZKoc1Q=
github.com/digitalocean/go-libvirt v0.0.0-20210108193637-3a8ae49ba8cd/go.mod h1:gtar3MgGsIO64GgphCHw1cbyxSI6qEuTIm9+izMmlfk=
@ -223,6 +238,7 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ
github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dylanmei/iso8601 v0.1.0 h1:812NGQDBcqquTfH5Yeo7lwR0nzx/cKdsmf3qMjPURUI=
github.com/dylanmei/iso8601 v0.1.0/go.mod h1:w9KhXSgIyROl1DefbMYIE7UVSIvELTbMrCfx+QkYnoQ=
github.com/dylanmei/winrmtest v0.0.0-20170819153634-c2fbb09e6c08 h1:0bp6/GrNOrTDtSXe9YYGCwf8jp5Fb/b+4a6MTRm4qzY=
@ -260,10 +276,13 @@ github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxm
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ini/ini v1.25.4 h1:Mujh4R/dH6YL8bxuISne3xX2+qcQ9p0IxKAP6ExWoUo=
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-ini/ini v1.62.0 h1:7VJT/ZXjzqSrvtraFp4ONq80hTcRQth1c9ZnQ3uNQvU=
github.com/go-ini/ini v1.62.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
@ -278,6 +297,7 @@ github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr
github.com/go-resty/resty/v2 v2.3.0 h1:JOOeAvjSlapTT92p8xiS19Zxev1neGikoHsXJeOq8So=
github.com/go-resty/resty/v2 v2.3.0/go.mod h1:UpN9CgLZNsv4e9XG50UU8xdI0F43UQ4HmxLBDwaroHU=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
@ -288,6 +308,7 @@ github.com/gofrs/flock v0.7.3/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
@ -296,6 +317,7 @@ github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3/go.mod h1:nPpo7qLxd6XL3hWJG/O60sR8ZKfMCiIoNap5GvD12KU=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
@ -393,9 +415,13 @@ github.com/gophercloud/utils v0.0.0-20200508015959-b0167b94122c/go.mod h1:ehWUbL
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg=
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hako/durafmt v0.0.0-20200710122514-c0fb7b4da026 h1:BpJ2o0OR5FV7vrkDYfXYVJQeMNWa8RhklZOpW2ITAIQ=
github.com/hako/durafmt v0.0.0-20200710122514-c0fb7b4da026/go.mod h1:5Scbynm8dF1XAPwIwkGPqzkM/shndPm79Jd1003hTjE=
github.com/hashicorp/aws-sdk-go-base v0.6.0/go.mod h1:2fRjWDv3jJBeN6mVWFHV6hFTNeFBx2gpDLQaZNxUVAY=
@ -438,7 +464,6 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-oracle-terraform v0.0.0-20181016190316-007121241b79 h1:RKu7yAXZTaQsxj1K9GDsh+QVw0+Wu1SWHxtbFN0n+hE=
github.com/hashicorp/go-oracle-terraform v0.0.0-20181016190316-007121241b79/go.mod h1:09jT3Y/OIsjTjQ2+3bkVNPDKqWcGIYYvjB2BEKVUdvc=
github.com/hashicorp/go-oracle-terraform v0.17.0 h1:gFiaeKf9MXLobhv7uqzPuDFULL6ymJpw1NJCXwSOgJ4=
github.com/hashicorp/go-oracle-terraform v0.17.0/go.mod h1:09jT3Y/OIsjTjQ2+3bkVNPDKqWcGIYYvjB2BEKVUdvc=
@ -553,6 +578,8 @@ github.com/hashicorp/packer-plugin-sdk v0.1.3/go.mod h1:xePpgQgQYv/bamiypx3hH9uk
github.com/hashicorp/packer-plugin-sdk v0.1.4/go.mod h1:xePpgQgQYv/bamiypx3hH9ukidxDdcN8q0R0wLi8IEQ=
github.com/hashicorp/packer-plugin-sdk v0.2.0 h1:A4Dq7p4y1vscY4gMzp7GQaXyDJYYhP4ukp4fapPSOY4=
github.com/hashicorp/packer-plugin-sdk v0.2.0/go.mod h1:0DiOMEBldmB0HEhp0npFSSygC8bIvW43pphEgWkp2WU=
github.com/hashicorp/packer-plugin-triton v0.0.0-20210421085122-768dd7c764d9 h1:No5oPI9Wa7FhTKkFJwI3hcfUVvEpgPC8QMcG9l/Vxzo=
github.com/hashicorp/packer-plugin-triton v0.0.0-20210421085122-768dd7c764d9/go.mod h1:XOAIiWYLbctBOsu41it/cL/ZjULAZ05YBhFm4H4M/lA=
github.com/hashicorp/packer-plugin-ucloud v0.0.1 h1:SC2F1BuXb6dKhY6fRdmAqTkuc17jlBIu/Ut0URJy8TU=
github.com/hashicorp/packer-plugin-ucloud v0.0.1/go.mod h1:xyMMmi/UPqFV3GT4eeX7wIqdoncNyrNuvdylnEQl1RU=
github.com/hashicorp/packer-plugin-vagrant v0.0.3 h1:BT8l8PM6TBawBRuhpvyuA4QSW9/FvE7rhGgVaiRpXz8=
@ -580,8 +607,12 @@ github.com/hyperonecom/h1-client-go v0.0.0-20191203060043-b46280e4c4a4 h1:mSmyzh
github.com/hyperonecom/h1-client-go v0.0.0-20191203060043-b46280e4c4a4/go.mod h1:yNUVHSleURKSaYUKq4Wx0i/vjCen2aq7CvPyHd/Vj2Q=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
github.com/jarcoal/httpmock v1.0.6/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
github.com/jarcoal/httpmock v1.0.8 h1:8kI16SoO6LQKgPE7PvQuV+YuD/inwHd7fOOe2zMbo4k=
github.com/jarcoal/httpmock v1.0.8/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
@ -596,8 +627,10 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62 h1:JHCT6xuyPUrbbgAPE/3dqlvUKzRHMNuTBKKUb6OeR/k=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA=
github.com/joyent/triton-go v1.8.5 h1:AXc1BJP3YGAvQXIdhdJt/PiARN5arHNXWK6Q6FeBing=
github.com/joyent/triton-go v1.8.5/go.mod h1:meGUPVGmmm+vhjIsOzfmJtuKpapVfWXJhUSLsr7Sv40=
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@ -609,6 +642,7 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@ -630,6 +664,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
github.com/kr/fs v0.0.0-20131111012553-2788f0dbd169/go.mod h1:glhvuHOU9Hy7/8PwwdtnarXqLagOX0b/TbZx2zLMqEg=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
@ -641,9 +676,11 @@ github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LE
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
github.com/labstack/echo/v4 v4.1.17/go.mod h1:Tn2yRQL/UclUalpb5rPdXDevbkJ+lp/2svdyFBg6CHQ=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/linode/linodego v0.14.0/go.mod h1:2ce3S00NrDqJfp4i55ZuSlT0U3cKNELNYACWBPI8Tnw=
github.com/linode/linodego v1.0.0 h1:Kq/8oPPk3ui/aVlzEObll5oBewHyzo/eJPnVPYuONVE=
github.com/linode/linodego v1.0.0/go.mod h1:XOWXRHjqeU2uPS84tKLgfWIfTlv3TYzCS0io4GOQzEI=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@ -669,6 +706,7 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
@ -720,11 +758,14 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ=
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20180105111133-96aac992fc8b/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.0-20180130162743-b8a9be070da4/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@ -745,6 +786,7 @@ github.com/packer-community/winrmcp v0.0.0-20180921204643-0fd363d6159a/go.mod h1
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
@ -761,15 +803,26 @@ github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXq
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/profitbricks/profitbricks-sdk-go v4.0.2+incompatible h1:ZoVHH6voxW9Onzo6z2yLtocVoN6mBocyDoqoyAMHokE=
github.com/profitbricks/profitbricks-sdk-go v4.0.2+incompatible/go.mod h1:T3/WrziK7fYH3C8ilAFAHe99R452/IzIG3YYkqaOFeQ=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.4.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
@ -778,6 +831,8 @@ github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7 h1:Do8ksLD4Nr3pA0x0hnLOLftZgkiTDvwPDShRTUxtXpE=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627/go.mod h1:7zjs06qF79/FKAJpBvFx3P8Ww4UTIMAe+lpNXDHziac=
github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
@ -786,6 +841,8 @@ github.com/shirou/gopsutil v2.18.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMT
github.com/shirou/gopsutil v3.21.1+incompatible h1:2LwXWdbjXwyDgq26Yy/OT4xozlpmssQfy/rtfhWb0bY=
github.com/shirou/gopsutil v3.21.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@ -795,11 +852,21 @@ github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:X
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
@ -814,6 +881,7 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tencentcloud/tencentcloud-sdk-go v3.0.222+incompatible h1:bs+0lcG4RELNbE8PsBC9oaPP0/qExr0DuEGnZyocm84=
github.com/tencentcloud/tencentcloud-sdk-go v3.0.222+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/ucloud/ucloud-sdk-go v0.16.3/go.mod h1:dyLmFHmUfgb4RZKYQP9IArlvQ2pxzFthfhwxRzOEPIw=
github.com/ucloud/ucloud-sdk-go v0.20.2 h1:ZNB38C7oZ2imCHEC79mVFvVT+ASkbryriOkZ+q2E0XI=
@ -822,8 +890,10 @@ github.com/ufilesdk-dev/ufile-gosdk v0.0.0-20190830075812-b4dbc4ef43a6/go.mod h1
github.com/ufilesdk-dev/ufile-gosdk v1.0.1 h1:TNtFN3vO8ghuxLKBwQqSELllHYP4rggvXCox8JtVV0Y=
github.com/ufilesdk-dev/ufile-gosdk v1.0.1/go.mod h1:R5FMQxkQ+QK/9Vz+jfnJP4rZIktYrRcWmuAnbOSkROI=
github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go v1.2.4 h1:cTciPbZ/VSOzCLKclmssnfQ/jyoVyOcJ3aoJyUV1Urc=
github.com/ugorji/go v1.2.4/go.mod h1:EuaSCk8iZMdIspsu6HXH7X2UGKw1ezO4wCfGszGmmo4=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v1.2.4 h1:C5VurWRRCKjuENsbM6GYVw8W++WVW9rSxoACKIvxzz8=
github.com/ugorji/go/codec v1.2.4/go.mod h1:bWBu1+kIRWcF8uMklKaJrR6fTWQOwAlrIzX22pHwryA=
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
@ -843,6 +913,8 @@ github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728/go.mod h1:x9o
github.com/xanzy/go-cloudstack v0.0.0-20190526095453-42f262b63ed0/go.mod h1:sBh287mCRwCz6zyXHMmw7sSZGPohVpnx+o+OY4M+i3A=
github.com/xanzy/go-cloudstack v2.4.1+incompatible h1:Oc4xa2+I94h1g/QJ+nHoq597nJz2KXzxuQx/weOx0AU=
github.com/xanzy/go-cloudstack v2.4.1+incompatible/go.mod h1:s3eL3z5pNXF5FVybcT+LIVdId8pYn709yv6v5mrkrQE=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yandex-cloud/go-genproto v0.0.0-20200915125933-33de72a328bd h1:o4pvS7D4OErKOM6y+/q6IfOa65OaentKbEDh1ABirE8=
github.com/yandex-cloud/go-genproto v0.0.0-20200915125933-33de72a328bd/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE=
github.com/yandex-cloud/go-sdk v0.0.0-20200921111412-ef15ded2014c h1:LJrgyICodRAgtBvOO2eCbhDDIoaJgeLa1tGQecqW9ac=
@ -862,6 +934,7 @@ github.com/zclconf/go-cty v1.8.2/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUA
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
github.com/zclconf/go-cty-yaml v1.0.1 h1:up11wlgAaDvlAGENcFDnZgkn0qUJurso7k6EpURKNF8=
github.com/zclconf/go-cty-yaml v1.0.1/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@ -875,12 +948,14 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@ -942,13 +1017,16 @@ golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@ -1012,6 +1090,9 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -1233,6 +1314,7 @@ google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaE
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
@ -1265,6 +1347,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -1281,9 +1364,11 @@ gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/jarcoal/httpmock.v1 v1.0.0-20181117152235-275e9df93516 h1:H6trpavCIuipdInWrab8l34Mf+GGVfphniHostMdMaQ=
gopkg.in/jarcoal/httpmock.v1 v1.0.0-20181117152235-275e9df93516/go.mod h1:d3R+NllX3X5e0zlG1Rful3uLvsGC/Q3OHut5464DEQw=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4=
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -1,218 +0,0 @@
---
description: >
The triton Packer builder is able to create new images for use with Triton.
These images can be used with both the Joyent public cloud (which is powered
by
Triton) as well with private Triton installations. This builder uses the
Triton
Cloud API to create images.
page_title: Triton - Builders
---
# Triton Builder
Type: `triton`
Artifact BuilderId: `joyent.triton`
The `triton` Packer builder is able to create new images for use with Triton.
These images can be used with both the [Joyent public
cloud](https://www.joyent.com/) (which is powered by Triton) as well with
private [Triton](https://github.com/joyent/triton) installations.
This builder uses the Triton Cloud API to create these images. Triton also
supports the Docker API however this builder does _not_. If you want to create
Docker images on Triton you should use the Packer Docker builder.
The builder creates and launches a temporary VM based on a specified source
image, runs any provisioning necessary, uses the Triton "VM to image"
functionality to create a reusable image and finally destroys the temporary VM.
This reusable image can then be used to launch new machines.
The builder does _not_ manage images. Once it creates an image, it is up to you
to use it or delete it.
~> **Private installations of Triton must have custom images enabled!** To
use the Triton builder with a private/on-prem installation of Joyent's Triton
software, you'll need an operator to manually [enable custom
images](https://docs.joyent.com/private-cloud/install/image-management) after
installing Triton. This is not a requirement for Joyent's public cloud offering
of Triton.
## Configuration Reference
There are many configuration options available for the builder. They are
segmented below into two categories: required and optional parameters.
In addition to the options listed here, a
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
builder. In addition to the options defined there, a private key file
can also be supplied to override the typical auto-generated key:
@include 'packer-plugin-sdk/communicator/SSH-Private-Key-File-not-required.mdx'
@include 'packer-plugin-sdk/communicator/SSH-Agent-Auth-not-required.mdx'
### Required:
- `triton_account` (string) - The username of the Triton account to use when
using the Triton Cloud API.
- `triton_key_id` (string) - The fingerprint of the public key of the SSH key
pair to use for authentication with the Triton Cloud API. If
`triton_key_material` is not set, it is assumed that the SSH agent has the
private key corresponding to this key ID loaded.
- `source_machine_image` (string) - The UUID of the image to base the new
image on. Triton supports multiple types of images, called 'brands' in
Triton / Joyent lingo, for contains and VM's. See the chapter [Containers
and virtual machines](https://docs.joyent.com/public-cloud/instances) in
the Joyent Triton documentation for detailed information. The following
brands are currently supported by this builder:`joyent` and`kvm`. The
choice of base image automatically decides the brand. On the Joyent public
cloud a valid `source_machine_image` could for example be
`70e3ae72-96b6-11e6-9056-9737fd4d0764` for version 16.3.1 of the 64bit
SmartOS base image (a 'joyent' brand image). `source_machine_image_filter`
can be used to populate this UUID.
- `source_machine_package` (string) - The Triton package to use while
building the image. Does not affect (and does not have to be the same) as
the package which will be used for a VM instance running this image. On the
Joyent public cloud this could for example be `g3-standard-0.5-smartos`.
- `image_name` (string) - The name the finished image in Triton will be
assigned. Maximum 512 characters but should in practice be much shorter
(think between 5 and 20 characters). For example `postgresql-95-server` for
an image used as a PostgreSQL 9.5 server.
- `image_version` (string) - The version string for this image. Maximum 128
characters. Any string will do but a format of `Major.Minor.Patch` is
strongly advised by Joyent. See [Semantic Versioning](http://semver.org/)
for more information on the `Major.Minor.Patch` versioning format.
### Optional:
- `triton_url` (string) - The URL of the Triton cloud API to use. If omitted
it will default to the `us-sw-1` region of the Joyent Public cloud. If you
are using your own private Triton installation you will have to supply the
URL of the cloud API of your own Triton installation.
- `triton_key_material` (string) - Path to the file in which the private key
of `triton_key_id` is stored. For example `/home/soandso/.ssh/id_rsa`. If
this is not specified, the SSH agent is used to sign requests with the
`triton_key_id` specified.
- `triton_user` (string) - The username of a user who has access to your
Triton account.
- `insecure_skip_tls_verify` - (bool) This allows skipping TLS verification
of the Triton endpoint. It is useful when connecting to a temporary Triton
installation such as Cloud-On-A-Laptop which does not generally use a
certificate signed by a trusted root CA. The default is `false`.
- `source_machine_firewall_enabled` (boolean) - Whether or not the firewall
of the VM used to create an image of is enabled. The Triton firewall only
filters inbound traffic to the VM. All outbound traffic is always allowed.
Currently this builder does not provide an interface to add specific
firewall rules. Unless you have a global rule defined in Triton which
allows SSH traffic enabling the firewall will interfere with the SSH
provisioner. The default is `false`.
- `source_machine_metadata` (object of key/value strings) - Triton metadata
applied to the VM used to create the image. Metadata can be used to pass
configuration information to the VM without the need for networking. See
[Using the metadata
API](https://docs.joyent.com/private-cloud/instances/using-mdata) in the
Joyent documentation for more information. This can for example be used to
set the `user-script` metadata key to have Triton start a user supplied
script after the VM has booted.
- `source_machine_name` (string) - Name of the VM used for building the
image. Does not affect (and does not have to be the same) as the name for a
VM instance running this image. Maximum 512 characters but should in
practice be much shorter (think between 5 and 20 characters). For example
`mysql-64-server-image-builder`. When omitted defaults to
`packer-builder-[image_name]`.
- `source_machine_networks` (array of strings) - The UUID's of Triton
networks added to the source machine used for creating the image. For
example if any of the provisioners which are run need Internet access you
will need to add the UUID's of the appropriate networks here. If this is
not specified, instances will be placed into the default Triton public and
internal networks.
- `source_machine_tags` (object of key/value strings) - Tags applied to the
VM used to create the image.
- `image_acls` (array of strings) - The UUID's of the users which will have
access to this image. When omitted only the owner (the Triton user whose
credentials are used) will have access to the image.
- `image_description` (string) - Description of the image. Maximum 512
characters.
- `image_eula_url` (string) - URL of the End User License Agreement (EULA)
for the image. Maximum 128 characters.
- `image_homepage` (string) - URL of the homepage where users can find
information about the image. Maximum 128 characters.
- `image_tags` (object of key/value strings) - Tag applied to the image.
- `source_machine_image_filter` (object) - Filters used to populate the
`source_machine_image` field. Example:
```json
{
"source_machine_image_filter": {
"name": "ubuntu-16.04",
"type": "lx-dataset",
"most_recent": true
}
}
```
## Basic Example
Below is a minimal example to create an image on the Joyent public cloud:
```json
{
"builders": [
{
"type": "triton",
"triton_account": "triton_username",
"triton_key_id": "6b:95:03:3d:d3:6e:52:69:01:96:1a:46:4a:8d:c1:7e",
"source_machine_name": "image-builder",
"source_machine_package": "g4-highcpu-128M",
"source_machine_image_filter": {
"name": "ubuntu-16.04",
"type": "lx-dataset",
"most_recent": "true"
},
"ssh_username": "root",
"image_name": "my_new_image",
"image_version": "1.0.0"
}
]
}
```
In the above example the SSH key used for `triton_key_material` (connecting to
the Cloud API) and the `ssh_private_key_file` (connecting to the VM once it has
started) are the same. This is because Triton automatically configures the root
users to be able to login via SSH with the same key used to create the VM via
the Cloud API. In more advanced scenarios for example when using a
`source_machine_image` one might use different credentials.
Available `triton_key_id`, `source_machine_package`, `source_machine_image`,
and `source_machine_networks` can be found by using the following [Triton
CLI](https://docs.joyent.com/public-cloud/api-access/cloudapi) commands:
`triton key list`, `triton package list`, `triton image list`, and
`triton network list` respectively.

View File

@ -728,10 +728,6 @@
"title": "Tencent Cloud",
"path": "builders/tencentcloud-cvm"
},
{
"title": "Triton",
"path": "builders/triton"
},
{
"title": "Yandex.Cloud",
"path": "builders/yandex"

View File

@ -146,6 +146,13 @@
"pluginTier": "community",
"version": "latest"
},
{
"title": "Triton",
"path": "triton",
"repo": "hashicorp/packer-plugin-triton",
"pluginTier": "community",
"version": "latest"
},
{
"title": "UCloud",
"path": "ucloud",