From ced2e945e3cc5ea9ef48a0896ce396f79ffb65c5 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 13 Feb 2020 12:59:47 -0800 Subject: [PATCH 01/41] make period stripping more strict so that users can disable provisiners by adding .old or whatever; this is pretty typical convention. --- config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.go b/config.go index 43293c04f..358014bc2 100644 --- a/config.go +++ b/config.go @@ -296,7 +296,7 @@ func (c *config) discoverSingle(glob string) (map[string]string, error) { } // If the filename has a ".", trim up to there - if idx := strings.Index(file, "."); idx >= 0 { + if idx := strings.Index(file, ".exe"); idx >= 0 { file = file[:idx] } From e2df4a80f8348dc5391b78cbe95c79e372fa7a76 Mon Sep 17 00:00:00 2001 From: r_takaishi Date: Fri, 6 Mar 2020 12:22:48 +0900 Subject: [PATCH 02/41] support keyboard interactive auth --- communicator/ssh/keyboard_interactive.go | 31 ++++++++++++++++++++++++ helper/communicator/step_connect_ssh.go | 3 +++ 2 files changed, 34 insertions(+) create mode 100644 communicator/ssh/keyboard_interactive.go diff --git a/communicator/ssh/keyboard_interactive.go b/communicator/ssh/keyboard_interactive.go new file mode 100644 index 000000000..5cf84acb2 --- /dev/null +++ b/communicator/ssh/keyboard_interactive.go @@ -0,0 +1,31 @@ +package ssh + +import ( + "golang.org/x/crypto/ssh" + "golang.org/x/crypto/ssh/terminal" + "log" + "syscall" +) + +func KeyboardInteractive() ssh.KeyboardInteractiveChallenge { + return func(user, instruction string, questions []string, echos []bool) ([]string, error) { + if len(questions) == 0 { + return []string{}, nil + } + + log.Printf("-- User: %s", user) + log.Printf("-- Instructions: %s", instruction) + for i, question := range questions { + log.Printf("-- Question %d: %s", i+1, question) + } + answers := make([]string, len(questions)) + for i := range questions { + s, err := terminal.ReadPassword(int(syscall.Stdin)) + if err != nil { + return nil, err + } + answers[i] = string(s) + } + return answers, nil + } +} diff --git a/helper/communicator/step_connect_ssh.go b/helper/communicator/step_connect_ssh.go index 1584c3e61..63fc44699 100644 --- a/helper/communicator/step_connect_ssh.go +++ b/helper/communicator/step_connect_ssh.go @@ -245,6 +245,9 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, ctx context.Contex func sshBastionConfig(config *Config) (*gossh.ClientConfig, error) { auth := make([]gossh.AuthMethod, 0, 2) + + auth = append(auth, gossh.KeyboardInteractive(ssh.KeyboardInteractive())) + if config.SSHBastionPassword != "" { auth = append(auth, gossh.Password(config.SSHBastionPassword), From 92c36eea8cb7befc07ec5bfd3a5a115e57d4defd Mon Sep 17 00:00:00 2001 From: r_takaishi Date: Fri, 6 Mar 2020 14:22:08 +0900 Subject: [PATCH 03/41] delete unnecessary conversion --- communicator/ssh/keyboard_interactive.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/communicator/ssh/keyboard_interactive.go b/communicator/ssh/keyboard_interactive.go index 5cf84acb2..1df616fff 100644 --- a/communicator/ssh/keyboard_interactive.go +++ b/communicator/ssh/keyboard_interactive.go @@ -20,7 +20,7 @@ func KeyboardInteractive() ssh.KeyboardInteractiveChallenge { } answers := make([]string, len(questions)) for i := range questions { - s, err := terminal.ReadPassword(int(syscall.Stdin)) + s, err := terminal.ReadPassword(syscall.Stdin) if err != nil { return nil, err } From 7cdb2e89e4149c94e873487a01c21def6c783f83 Mon Sep 17 00:00:00 2001 From: r_takaishi Date: Fri, 6 Mar 2020 14:34:17 +0900 Subject: [PATCH 04/41] use os.Stdin --- communicator/ssh/keyboard_interactive.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/communicator/ssh/keyboard_interactive.go b/communicator/ssh/keyboard_interactive.go index 1df616fff..2cd983970 100644 --- a/communicator/ssh/keyboard_interactive.go +++ b/communicator/ssh/keyboard_interactive.go @@ -4,7 +4,7 @@ import ( "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/terminal" "log" - "syscall" + "os" ) func KeyboardInteractive() ssh.KeyboardInteractiveChallenge { @@ -20,7 +20,7 @@ func KeyboardInteractive() ssh.KeyboardInteractiveChallenge { } answers := make([]string, len(questions)) for i := range questions { - s, err := terminal.ReadPassword(syscall.Stdin) + s, err := terminal.ReadPassword(int(os.Stdin.Fd())) if err != nil { return nil, err } From 4447d2893880c7a864ddceb083196d6b2c21c67b Mon Sep 17 00:00:00 2001 From: r_takaishi Date: Fri, 6 Mar 2020 15:23:06 +0900 Subject: [PATCH 05/41] fix lint --- communicator/ssh/keyboard_interactive.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/communicator/ssh/keyboard_interactive.go b/communicator/ssh/keyboard_interactive.go index 2cd983970..33dd68463 100644 --- a/communicator/ssh/keyboard_interactive.go +++ b/communicator/ssh/keyboard_interactive.go @@ -1,10 +1,11 @@ package ssh import ( - "golang.org/x/crypto/ssh" - "golang.org/x/crypto/ssh/terminal" "log" "os" + + "golang.org/x/crypto/ssh" + "golang.org/x/crypto/ssh/terminal" ) func KeyboardInteractive() ssh.KeyboardInteractiveChallenge { From 0c6249df7f1359d6bf3f2770bea7845947cd6db0 Mon Sep 17 00:00:00 2001 From: r_takaishi Date: Mon, 9 Mar 2020 11:54:53 +0900 Subject: [PATCH 06/41] use tty when IsTerminal is false --- communicator/ssh/keyboard_interactive.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/communicator/ssh/keyboard_interactive.go b/communicator/ssh/keyboard_interactive.go index 33dd68463..66e7fef6d 100644 --- a/communicator/ssh/keyboard_interactive.go +++ b/communicator/ssh/keyboard_interactive.go @@ -1,11 +1,10 @@ package ssh import ( - "log" - "os" - "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/terminal" + "log" + "os" ) func KeyboardInteractive() ssh.KeyboardInteractiveChallenge { @@ -21,7 +20,18 @@ func KeyboardInteractive() ssh.KeyboardInteractiveChallenge { } answers := make([]string, len(questions)) for i := range questions { - s, err := terminal.ReadPassword(int(os.Stdin.Fd())) + var fd int + if terminal.IsTerminal(int(os.Stdin.Fd())) { + fd = int(os.Stdin.Fd()) + } else { + tty, err := os.Open("/dev/tty") + if err != nil { + return nil, err + } + defer tty.Close() + fd = int(tty.Fd()) + } + s, err := terminal.ReadPassword(fd) if err != nil { return nil, err } From a0dfcf3715ac90b8ea1568b1d8fcb0e93aad7819 Mon Sep 17 00:00:00 2001 From: r_takaishi Date: Mon, 9 Mar 2020 11:58:53 +0900 Subject: [PATCH 07/41] use log --- communicator/ssh/keyboard_interactive.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/communicator/ssh/keyboard_interactive.go b/communicator/ssh/keyboard_interactive.go index 66e7fef6d..5f1013bd3 100644 --- a/communicator/ssh/keyboard_interactive.go +++ b/communicator/ssh/keyboard_interactive.go @@ -13,10 +13,10 @@ func KeyboardInteractive() ssh.KeyboardInteractiveChallenge { return []string{}, nil } - log.Printf("-- User: %s", user) - log.Printf("-- Instructions: %s", instruction) + log.Printf("[INFO] -- User: %s", user) + log.Printf("[INFO] -- Instructions: %s", instruction) for i, question := range questions { - log.Printf("-- Question %d: %s", i+1, question) + log.Printf("[INFO] -- Question %d: %s", i+1, question) } answers := make([]string, len(questions)) for i := range questions { From 34bb0429d0b75945807414585d8e20afb78ce820 Mon Sep 17 00:00:00 2001 From: r_takaishi Date: Wed, 11 Mar 2020 10:37:57 +0900 Subject: [PATCH 08/41] keyboard-interactive used when ssh_bastion_host is true. --- helper/communicator/config.go | 2 ++ helper/communicator/step_connect_ssh.go | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/helper/communicator/config.go b/helper/communicator/config.go index 83de5aea0..ae089a9af 100644 --- a/helper/communicator/config.go +++ b/helper/communicator/config.go @@ -132,6 +132,8 @@ type SSH struct { SSHBastionUsername string `mapstructure:"ssh_bastion_username"` // The password to use to authenticate with the bastion host. SSHBastionPassword string `mapstructure:"ssh_bastion_password"` + // If `true`, the keyboard-interactive used to authenticate with bastion host. + SSHBastionInteractive bool `mapstructure:"ssh_bastion_interactive"` // Path to a PEM encoded private key file to use to authenticate with the // bastion host. The `~` can be used in path and will be expanded to the // home directory of current user. diff --git a/helper/communicator/step_connect_ssh.go b/helper/communicator/step_connect_ssh.go index 63fc44699..8eb1c5156 100644 --- a/helper/communicator/step_connect_ssh.go +++ b/helper/communicator/step_connect_ssh.go @@ -246,7 +246,9 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, ctx context.Contex func sshBastionConfig(config *Config) (*gossh.ClientConfig, error) { auth := make([]gossh.AuthMethod, 0, 2) - auth = append(auth, gossh.KeyboardInteractive(ssh.KeyboardInteractive())) + if config.SSHBastionInteractive { + auth = append(auth, gossh.KeyboardInteractive(ssh.KeyboardInteractive())) + } if config.SSHBastionPassword != "" { auth = append(auth, From 0230c078e03cc8af902c9bc3709f834587b5db26 Mon Sep 17 00:00:00 2001 From: r_takaishi Date: Wed, 11 Mar 2020 10:53:59 +0900 Subject: [PATCH 09/41] write docs --- .../partials/helper/communicator/_SSH-not-required.html.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/source/partials/helper/communicator/_SSH-not-required.html.md b/website/source/partials/helper/communicator/_SSH-not-required.html.md index 629654786..837735e5e 100644 --- a/website/source/partials/helper/communicator/_SSH-not-required.html.md +++ b/website/source/partials/helper/communicator/_SSH-not-required.html.md @@ -65,6 +65,8 @@ - `ssh_bastion_password` (string) - The password to use to authenticate with the bastion host. +- `ssh_bastion_interactive` (bool) - If `true`, the keyboard-interactive used to authenticate with bastion host. + - `ssh_bastion_private_key_file` (string) - Path to a PEM encoded private key file to use to authenticate with the bastion host. The `~` can be used in path and will be expanded to the home directory of current user. From 4bb4f7617f7dfa1adfa1d2e2f1580a2ba56f4d8f Mon Sep 17 00:00:00 2001 From: r_takaishi Date: Wed, 11 Mar 2020 11:04:59 +0900 Subject: [PATCH 10/41] need white spaces --- .../partials/helper/communicator/_SSH-not-required.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/partials/helper/communicator/_SSH-not-required.html.md b/website/source/partials/helper/communicator/_SSH-not-required.html.md index 837735e5e..5fe63d562 100644 --- a/website/source/partials/helper/communicator/_SSH-not-required.html.md +++ b/website/source/partials/helper/communicator/_SSH-not-required.html.md @@ -66,7 +66,7 @@ - `ssh_bastion_password` (string) - The password to use to authenticate with the bastion host. - `ssh_bastion_interactive` (bool) - If `true`, the keyboard-interactive used to authenticate with bastion host. - + - `ssh_bastion_private_key_file` (string) - Path to a PEM encoded private key file to use to authenticate with the bastion host. The `~` can be used in path and will be expanded to the home directory of current user. From 063dd5c133ed2d665670aadaaf3640beb380a58f Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Wed, 11 Mar 2020 09:55:40 -0700 Subject: [PATCH 11/41] fix interpolation when env vars interpolate before user vars --- packer/core.go | 60 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/packer/core.go b/packer/core.go index a3f33a816..16780d086 100644 --- a/packer/core.go +++ b/packer/core.go @@ -2,6 +2,7 @@ package packer import ( "fmt" + "regexp" "sort" "strings" @@ -346,13 +347,24 @@ func (c *Core) validate() error { return err } -func (c *Core) init() error { - if c.variables == nil { - c.variables = make(map[string]string) +func isDoneInterpolating(v string) (bool, error) { + // Check for whether the var contains any more references to `user`, wrapped + // in interpolation syntax. + filter := "{{\\s*|user\\s*|\\x60?.*\\x60?}}" + matched, err := regexp.MatchString(filter, v) + if err != nil { + return false, fmt.Errorf("Can't tell if interpolation is done: %s", err) } - // Go through the variables and interpolate the environment and - // user variables + if matched { + // not done interpolating; there's still a call to "user" in a template + // engine + return false, nil + } + // No more calls to "user" as a template engine, so we're done. + return true, nil +} +func (c *Core) renderVarsRecursively() (*interpolate.Context, error) { ctx := c.Context() ctx.EnableEnv = true ctx.UserVariables = make(map[string]string) @@ -386,15 +398,15 @@ func (c *Core) init() error { // We need to read the keys from both, then loop over all of them to figure // out the appropriate interpolations. - allVariables := make(map[string]string) + repeatMap := make(map[string]string) // load in template variables for k, v := range c.Template.Variables { - allVariables[k] = v.Default + repeatMap[k] = v.Default } // overwrite template variables with command-line-read variables for k, v := range c.variables { - allVariables[k] = v + repeatMap[k] = v } // Regex to exclude any build function variable or template variable @@ -405,7 +417,7 @@ func (c *Core) init() error { for i := 0; i < 100; i++ { shouldRetry = false // First, loop over the variables in the template - for k, v := range allVariables { + for k, v := range repeatMap { // Interpolate the default renderedV, err := interpolate.RenderRegex(v, ctx, renderFilter) switch err.(type) { @@ -415,16 +427,27 @@ func (c *Core) init() error { changed = true c.variables[k] = renderedV ctx.UserVariables = c.variables + // Remove fully-interpolated variables from the map, and flag + // variables that still need interpolating for a repeat. + done, err := isDoneInterpolating(v) + if err != nil { + return ctx, err + } + if done { + delete(repeatMap, k) + } else { + shouldRetry = true + } case ttmp.ExecError: castError := err.(ttmp.ExecError) if strings.Contains(castError.Error(), interpolate.ErrVariableNotSetString) { shouldRetry = true failedInterpolation = fmt.Sprintf(`"%s": "%s"; error: %s`, k, v, err) } else { - return err + return ctx, err } default: - return fmt.Errorf( + return ctx, fmt.Errorf( // unexpected interpolation error: abort the run "error interpolating default value for '%s': %s", k, err) @@ -436,12 +459,25 @@ func (c *Core) init() error { } if !changed && shouldRetry { - return fmt.Errorf("Failed to interpolate %s: Please make sure that "+ + return ctx, fmt.Errorf("Failed to interpolate %s: Please make sure that "+ "the variable you're referencing has been defined; Packer treats "+ "all variables used to interpolate other user varaibles as "+ "required.", failedInterpolation) } + return ctx, nil +} + +func (c *Core) init() error { + if c.variables == nil { + c.variables = make(map[string]string) + } + // Go through the variables and interpolate the environment and + // user variables + ctx, err := c.renderVarsRecursively() + if err != nil { + return err + } for _, v := range c.Template.SensitiveVariables { secret := ctx.UserVariables[v.Key] c.secrets = append(c.secrets, secret) From 52f03de0f0d68d0ed6f0c5b7f17921d6082ed2b4 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Wed, 11 Mar 2020 10:49:45 -0700 Subject: [PATCH 12/41] adding tests --- packer/core_test.go | 94 ++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/packer/core_test.go b/packer/core_test.go index 90f59de1d..70d7f9072 100644 --- a/packer/core_test.go +++ b/packer/core_test.go @@ -463,37 +463,15 @@ func TestCoreValidate(t *testing.T) { Vars map[string]string Err bool }{ - { - "validate-dup-builder.json", - nil, - true, - }, + {"validate-dup-builder.json", nil, true}, // Required variable not set - { - "validate-req-variable.json", - nil, - true, - }, - - { - "validate-req-variable.json", - map[string]string{"foo": "bar"}, - false, - }, + {"validate-req-variable.json", nil, true}, + {"validate-req-variable.json", map[string]string{"foo": "bar"}, false}, // Min version good - { - "validate-min-version.json", - map[string]string{"foo": "bar"}, - false, - }, - - { - "validate-min-version-high.json", - map[string]string{"foo": "bar"}, - true, - }, + {"validate-min-version.json", map[string]string{"foo": "bar"}, false}, + {"validate-min-version-high.json", map[string]string{"foo": "bar"}, true}, } for _, tc := range cases { @@ -700,6 +678,68 @@ func TestSensitiveVars(t *testing.T) { } } +// Normally I wouldn't test a little helper function, but it's regex. +func testisDoneInterpolating(t *testing.T) { + cases := []struct { + inputString string + expectedBool bool + expectedErr bool + }{ + // Many of these tests are just exercising the regex to make sure it + // doesnt get confused by different kinds of whitespace + {"charmander-{{ user `spacesaroundticks` }}", false, false}, + {"pidgey-{{ user `partyparrot`}}", false, false}, + {"jigglypuff-{{ user`notickspaaces`}}", false, false}, + {"eevee-{{user`nospaces`}}", false, false}, + {"staryu-{{ user `somanyspaces` }}", false, false}, + {"{{ user `somanyspaces` }}-{{isotime}}", false, false}, + // Make sure that we only flag on "user" when it's in the right set of + // brackets, in a properly declared template engine format + {"missingno-{{ user `missingbracket` }", true, false}, + {"missing2-{user ``missingopenbrackets }}", true, false}, + {"wat-userjustinname", true, false}, + // Any functions that aren't "user" should have already been properly + // interpolated by the time this is called, so these cases aren't + // realistic. That said, this makes it clear that this function doesn't + // care about anything but the user function + {"pokemon-{{ isotime }}", true, false}, + {"squirtle-{{ env `water`}}", true, false}, + {"bulbasaur-notinterpolated", true, false}, + {"extra-{{thisfunc `user`}}", true, false}, + } + for _, tc := range cases { + done, err := isDoneInterpolating(tc.inputString) + if (err != nil) != tc.expectedErr { + t.Fatalf("Test case failed. Error: %s expected error: "+ + "%t test string: %s", err, tc.expectedErr, tc.inputString) + } + if done != tc.expectedBool { + t.Fatalf("Test case failed. inputString: %s. "+ + "Expected done = %t but got done = %t", tc.inputString, + tc.expectedBool, done) + } + } +} + +// func testCoreBuildWithInterpolatedEnvVars(t *testing.T) { +// // Not a fan of using env vars in tests but in this case we need to make +// // sure they get interpolated properly. +// os.Setenv("CI_COMMIT_REF_NAME", "working") +// os.Setenv("OUTPUT_DIR", "/u01/artifacts") +// os.Setenv("OS_VERSION", "6") +// os.Setenv("OS", "rhel") +// os.Setenv("BASE_POSTFIX", "base") +// os.Setenv("RULE", "vbox") +// os.Setenv("POSTFIX", "base") + +// packer build \ +// -var-file=common/vsphere.variables.json \ +// -var-file=common/variables.json \ +// -only=vbox-rhel-base \ +// common/linux/redhat/template.json + +// } + func testCoreTemplate(t *testing.T, c *CoreConfig, p string) { tpl, err := template.ParseFile(p) if err != nil { From 051155270f34a551f97b896f33fa1fad23f1dd2b Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Wed, 11 Mar 2020 12:48:35 -0700 Subject: [PATCH 13/41] add test for fixed behavior --- packer/core_test.go | 71 ++++++++++++++----- .../complex-recursed-env-user-var-file.json | 11 +++ 2 files changed, 66 insertions(+), 16 deletions(-) create mode 100644 packer/test-fixtures/complex-recursed-env-user-var-file.json diff --git a/packer/core_test.go b/packer/core_test.go index 70d7f9072..e2bfb86d7 100644 --- a/packer/core_test.go +++ b/packer/core_test.go @@ -721,24 +721,63 @@ func testisDoneInterpolating(t *testing.T) { } } -// func testCoreBuildWithInterpolatedEnvVars(t *testing.T) { -// // Not a fan of using env vars in tests but in this case we need to make -// // sure they get interpolated properly. -// os.Setenv("CI_COMMIT_REF_NAME", "working") -// os.Setenv("OUTPUT_DIR", "/u01/artifacts") -// os.Setenv("OS_VERSION", "6") -// os.Setenv("OS", "rhel") -// os.Setenv("BASE_POSTFIX", "base") -// os.Setenv("RULE", "vbox") -// os.Setenv("POSTFIX", "base") +func TestEnvAndFileVars(t *testing.T) { + os.Setenv("INTERPOLATE_TEST_ENV_1", "bulbasaur") + os.Setenv("INTERPOLATE_TEST_ENV_3", "/path/to/nowhere") + os.Setenv("INTERPOLATE_TEST_ENV_2", "5") + os.Setenv("INTERPOLATE_TEST_ENV_4", "bananas") -// packer build \ -// -var-file=common/vsphere.variables.json \ -// -var-file=common/variables.json \ -// -only=vbox-rhel-base \ -// common/linux/redhat/template.json + // run the interpolations a bunch of times, because we have had issues + // where the behavior is different based on the order in which the + // vars are interpolated + for i := 0; i < 100; i++ { + f, err := os.Open(fixtureDir("complex-recursed-env-user-var-file.json")) + if err != nil { + t.Fatalf("err: %s", err) + } -// } + tpl, err := template.Parse(f) + f.Close() + if err != nil { + t.Fatalf("err: %s\n\n%s", "complex-recursed-env-user-var-file.json", err) + } + + ccf, err := NewCore(&CoreConfig{ + Template: tpl, + Version: "1.0.0", + Variables: map[string]string{ + "var_1": "partyparrot", + "var_2": "{{user `env_1`}}-{{user `env_2`}}{{user `env_3`}}-{{user `var_1`}}", + "final_var": "{{user `env_1`}}/{{user `env_2`}}/{{user `env_4`}}{{user `env_3`}}-{{user `var_1`}}/vmware/{{user `var_2`}}.vmx", + }, + }) + expected := map[string]string{ + "var_1": "partyparrot", + "var_2": "bulbasaur-5/path/to/nowhere-partyparrot", + "final_var": "bulbasaur/5/bananas/path/to/nowhere-partyparrot/vmware/bulbasaur-5/path/to/nowhere-partyparrot.vmx", + "env_1": "bulbasaur", + "env_2": "5", + "env_3": "/path/to/nowhere", + "env_4": "bananas", + } + if err != nil { + t.Fatalf("err: %s\n\n%s", "complex-recursed-env-user-var-file.json", err) + } + for k, v := range ccf.variables { + if expected[k] != v { + t.Fatalf("Expected value %s for key %s but got %s", + expected[k], k, v) + } + } + + } + + // Clean up env vars + os.Unsetenv("INTERPOLATE_TEST_ENV_1") + os.Unsetenv("INTERPOLATE_TEST_ENV_3") + os.Unsetenv("INTERPOLATE_TEST_ENV_2") + os.Unsetenv("INTERPOLATE_TEST_ENV_4") +} func testCoreTemplate(t *testing.T, c *CoreConfig, p string) { tpl, err := template.ParseFile(p) diff --git a/packer/test-fixtures/complex-recursed-env-user-var-file.json b/packer/test-fixtures/complex-recursed-env-user-var-file.json new file mode 100644 index 000000000..bffb4b1ca --- /dev/null +++ b/packer/test-fixtures/complex-recursed-env-user-var-file.json @@ -0,0 +1,11 @@ +{ + "variables": { + "env_1": "{{ env `INTERPOLATE_TEST_ENV_1` }}", + "env_2": "{{ env `INTERPOLATE_TEST_ENV_2` }}", + "env_3": "{{ env `INTERPOLATE_TEST_ENV_3` }}", + "env_4": "{{ env `INTERPOLATE_TEST_ENV_4` }}" + }, + "builders": [{ + "type": "test" + }] +} \ No newline at end of file From c3d793255ecbcb73e7ad099c89f64d6461acd08b Mon Sep 17 00:00:00 2001 From: "Paul Cichonski (pcichons)" Date: Wed, 11 Mar 2020 18:45:05 -0400 Subject: [PATCH 14/41] Do not test if NIC is reachable when ssh bastion is required Relates to https://github.com/hashicorp/packer/issues/8866 --- builder/vmware/common/driver_esx5.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/builder/vmware/common/driver_esx5.go b/builder/vmware/common/driver_esx5.go index 109b91967..d2896989e 100644 --- a/builder/vmware/common/driver_esx5.go +++ b/builder/vmware/common/driver_esx5.go @@ -495,6 +495,15 @@ func (d *ESX5Driver) CommHost(state multistep.StateBag) (string, error) { if record["IPAddress"] == "0.0.0.0" { continue } + + // if ssh is going through a bastion, we can't easily check if the nic is reachable on the network + // so just pick the first one that is not 0.0.0.0 + if sshc.SSHBastionHost != "" { + address := record["IPAddress"] + state.Put("vm_address", address) + return address, nil + } + // When multiple NICs are connected to the same network, choose // one that has a route back. This Dial should ensure that. conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", record["IPAddress"], port), 2*time.Second) From c8300b620a581f3c2fa9f505621f35d568f4a25a Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Thu, 12 Mar 2020 14:27:56 +0100 Subject: [PATCH 15/41] allow to use hcl files as var files in HCL mode fix #8781 --- command/build.go | 2 +- command/meta.go | 14 +++++++++++++- hcl2template/common_test.go | 3 ++- hcl2template/parser.go | 19 +++++++++++++++++-- hcl2template/types.build_test.go | 12 ++++++------ hcl2template/types.packer_config.go | 4 ++-- hcl2template/types.packer_config_test.go | 10 +++++----- hcl2template/types.source_test.go | 10 +++++----- hcl2template/types.variables_test.go | 18 +++++++++--------- helper/flag-kv/flag_strings.go | 16 ++++++++++++++++ 10 files changed, 76 insertions(+), 32 deletions(-) create mode 100644 helper/flag-kv/flag_strings.go diff --git a/command/build.go b/command/build.go index 2ea4fcc85..64a352678 100644 --- a/command/build.go +++ b/command/build.go @@ -104,7 +104,7 @@ func (c *BuildCommand) GetBuildsFromHCL(path string) ([]packer.Build, int) { PostProcessorsSchemas: c.CoreConfig.Components.PostProcessorStore, } - builds, diags := parser.Parse(path, c.flagVars) + builds, diags := parser.Parse(path, c.varFiles, c.flagVars) { // write HCL errors/diagnostics if any. b := bytes.NewBuffer(nil) diff --git a/command/meta.go b/command/meta.go index b92116428..8d28a1924 100644 --- a/command/meta.go +++ b/command/meta.go @@ -32,6 +32,7 @@ type Meta struct { Version string // These are set by command-line flags + varFiles []string flagVars map[string]string } @@ -41,6 +42,17 @@ func (m *Meta) Core(tpl *template.Template) (*packer.Core, error) { // Copy the config so we don't modify it config := *m.CoreConfig config.Template = tpl + + fj := &kvflag.FlagJSON{} + for _, file := range m.varFiles { + err := fj.Set(file) + if err != nil { + return nil, err + } + } + for k, v := range *fj { + m.flagVars[k] = v + } config.Variables = m.flagVars // Init the core @@ -117,7 +129,7 @@ func (m *Meta) FlagSet(n string, fs FlagSetFlags) *flag.FlagSet { // FlagSetVars tells us what variables to use if fs&FlagSetVars != 0 { f.Var((*kvflag.Flag)(&m.flagVars), "var", "") - f.Var((*kvflag.FlagJSON)(&m.flagVars), "var-file", "") + f.Var((*kvflag.StringSlice)(&m.varFiles), "var-file", "") } // Create an io.Writer that writes to our Ui properly for errors. diff --git a/hcl2template/common_test.go b/hcl2template/common_test.go index b0dfedb82..fd472cf3b 100644 --- a/hcl2template/common_test.go +++ b/hcl2template/common_test.go @@ -37,6 +37,7 @@ func getBasicParser() *Parser { type parseTestArgs struct { filename string vars map[string]string + varFiles []string } type parseTest struct { @@ -58,7 +59,7 @@ func testParse(t *testing.T, tests []parseTest) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - gotCfg, gotDiags := tt.parser.parse(tt.args.filename, tt.args.vars) + gotCfg, gotDiags := tt.parser.parse(tt.args.filename, tt.args.varFiles, tt.args.vars) if tt.parseWantDiags == (gotDiags == nil) { t.Fatalf("Parser.parse() unexpected %q diagnostics.", gotDiags) } diff --git a/hcl2template/parser.go b/hcl2template/parser.go index 3bf48294e..35061f932 100644 --- a/hcl2template/parser.go +++ b/hcl2template/parser.go @@ -52,7 +52,7 @@ const ( hcl2VarJsonFileExt = ".auto.pkrvars.json" ) -func (p *Parser) parse(filename string, vars map[string]string) (*PackerConfig, hcl.Diagnostics) { +func (p *Parser) parse(filename string, varFiles []string, argVars map[string]string) (*PackerConfig, hcl.Diagnostics) { var files []*hcl.File var diags hcl.Diagnostics @@ -60,6 +60,7 @@ func (p *Parser) parse(filename string, vars map[string]string) (*PackerConfig, // parse config files { hclFiles, jsonFiles, moreDiags := GetHCL2Files(filename, hcl2FileExt, hcl2JsonFileExt) + diags = append(diags, moreDiags...) if len(hclFiles)+len(jsonFiles) == 0 { diags = append(moreDiags, &hcl.Diagnostic{ Severity: hcl.DiagError, @@ -111,6 +112,20 @@ func (p *Parser) parse(filename string, vars map[string]string) (*PackerConfig, { hclVarFiles, jsonVarFiles, moreDiags := GetHCL2Files(filename, hcl2VarFileExt, hcl2VarJsonFileExt) diags = append(diags, moreDiags...) + for _, file := range varFiles { + switch filepath.Ext(file) { + case ".hcl": + hclVarFiles = append(hclVarFiles, file) + case ".json": + jsonVarFiles = append(jsonVarFiles, file) + default: + diags = append(moreDiags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Could not guess format of " + file, + Detail: "A var file must be suffixed with `.hcl` or `.json`.", + }) + } + } var varFiles []*hcl.File for _, filename := range hclVarFiles { f, moreDiags := p.ParseHCLFile(filename) @@ -123,7 +138,7 @@ func (p *Parser) parse(filename string, vars map[string]string) (*PackerConfig, varFiles = append(varFiles, f) } - diags = append(diags, cfg.collectInputVariableValues(os.Environ(), varFiles, vars)...) + diags = append(diags, cfg.collectInputVariableValues(os.Environ(), varFiles, argVars)...) } _, moreDiags := cfg.InputVariables.Values() diff --git a/hcl2template/types.build_test.go b/hcl2template/types.build_test.go index dba35bf3a..7d45d022d 100644 --- a/hcl2template/types.build_test.go +++ b/hcl2template/types.build_test.go @@ -13,7 +13,7 @@ func TestParse_build(t *testing.T) { tests := []parseTest{ {"basic build no src", defaultParser, - parseTestArgs{"testdata/build/basic.pkr.hcl", nil}, + parseTestArgs{"testdata/build/basic.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "build"), Builds: Builds{ @@ -47,7 +47,7 @@ func TestParse_build(t *testing.T) { }, {"untyped provisioner", defaultParser, - parseTestArgs{"testdata/build/provisioner_untyped.pkr.hcl", nil}, + parseTestArgs{"testdata/build/provisioner_untyped.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "build"), Builds: nil, @@ -58,7 +58,7 @@ func TestParse_build(t *testing.T) { }, {"inexistent provisioner", defaultParser, - parseTestArgs{"testdata/build/provisioner_inexistent.pkr.hcl", nil}, + parseTestArgs{"testdata/build/provisioner_inexistent.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "build"), Builds: nil, @@ -69,7 +69,7 @@ func TestParse_build(t *testing.T) { }, {"untyped post-processor", defaultParser, - parseTestArgs{"testdata/build/post-processor_untyped.pkr.hcl", nil}, + parseTestArgs{"testdata/build/post-processor_untyped.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "build"), Builds: nil, @@ -80,7 +80,7 @@ func TestParse_build(t *testing.T) { }, {"inexistent post-processor", defaultParser, - parseTestArgs{"testdata/build/post-processor_inexistent.pkr.hcl", nil}, + parseTestArgs{"testdata/build/post-processor_inexistent.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "build"), Builds: nil, @@ -91,7 +91,7 @@ func TestParse_build(t *testing.T) { }, {"invalid source", defaultParser, - parseTestArgs{"testdata/build/invalid_source_reference.pkr.hcl", nil}, + parseTestArgs{"testdata/build/invalid_source_reference.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "build"), Builds: nil, diff --git a/hcl2template/types.packer_config.go b/hcl2template/types.packer_config.go index 0d61e3069..3f52092d7 100644 --- a/hcl2template/types.packer_config.go +++ b/hcl2template/types.packer_config.go @@ -287,8 +287,8 @@ func (p *Parser) getBuilds(cfg *PackerConfig) ([]packer.Build, hcl.Diagnostics) // // Parse then return a slice of packer.Builds; which are what packer core uses // to run builds. -func (p *Parser) Parse(path string, vars map[string]string) ([]packer.Build, hcl.Diagnostics) { - cfg, diags := p.parse(path, vars) +func (p *Parser) Parse(path string, varFiles []string, argVars map[string]string) ([]packer.Build, hcl.Diagnostics) { + cfg, diags := p.parse(path, varFiles, argVars) if diags.HasErrors() { return nil, diags } diff --git a/hcl2template/types.packer_config_test.go b/hcl2template/types.packer_config_test.go index d84cef1fc..ae0b5030d 100644 --- a/hcl2template/types.packer_config_test.go +++ b/hcl2template/types.packer_config_test.go @@ -18,7 +18,7 @@ func TestParser_complete(t *testing.T) { tests := []parseTest{ {"working build", defaultParser, - parseTestArgs{"testdata/complete", nil}, + parseTestArgs{"testdata/complete", nil, nil}, &PackerConfig{ Basedir: "testdata/complete", InputVariables: Variables{ @@ -128,7 +128,7 @@ func TestParser_complete(t *testing.T) { }, {"dir with no config files", defaultParser, - parseTestArgs{"testdata/empty", nil}, + parseTestArgs{"testdata/empty", nil, nil}, nil, true, true, nil, @@ -136,14 +136,14 @@ func TestParser_complete(t *testing.T) { }, {name: "inexistent dir", parser: defaultParser, - args: parseTestArgs{"testdata/inexistent", nil}, + args: parseTestArgs{"testdata/inexistent", nil, nil}, parseWantCfg: nil, parseWantDiags: true, parseWantDiagHasErrors: true, }, {name: "folder named build.pkr.hcl with an unknown src", parser: defaultParser, - args: parseTestArgs{"testdata/build.pkr.hcl", nil}, + args: parseTestArgs{"testdata/build.pkr.hcl", nil, nil}, parseWantCfg: &PackerConfig{ Basedir: "testdata/build.pkr.hcl", Builds: Builds{ @@ -166,7 +166,7 @@ func TestParser_complete(t *testing.T) { }, {name: "unknown block type", parser: defaultParser, - args: parseTestArgs{"testdata/unknown", nil}, + args: parseTestArgs{"testdata/unknown", nil, nil}, parseWantCfg: &PackerConfig{ Basedir: "testdata/unknown", }, diff --git a/hcl2template/types.source_test.go b/hcl2template/types.source_test.go index f5c9d0855..423d20422 100644 --- a/hcl2template/types.source_test.go +++ b/hcl2template/types.source_test.go @@ -13,7 +13,7 @@ func TestParse_source(t *testing.T) { tests := []parseTest{ {"two basic sources", defaultParser, - parseTestArgs{"testdata/sources/basic.pkr.hcl", nil}, + parseTestArgs{"testdata/sources/basic.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "sources"), Sources: map[SourceRef]*SourceBlock{ @@ -32,7 +32,7 @@ func TestParse_source(t *testing.T) { }, {"untyped source", defaultParser, - parseTestArgs{"testdata/sources/untyped.pkr.hcl", nil}, + parseTestArgs{"testdata/sources/untyped.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "sources"), }, @@ -42,7 +42,7 @@ func TestParse_source(t *testing.T) { }, {"unnamed source", defaultParser, - parseTestArgs{"testdata/sources/unnamed.pkr.hcl", nil}, + parseTestArgs{"testdata/sources/unnamed.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "sources"), }, @@ -52,7 +52,7 @@ func TestParse_source(t *testing.T) { }, {"inexistent source", defaultParser, - parseTestArgs{"testdata/sources/inexistent.pkr.hcl", nil}, + parseTestArgs{"testdata/sources/inexistent.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "sources"), }, @@ -62,7 +62,7 @@ func TestParse_source(t *testing.T) { }, {"duplicate source", defaultParser, - parseTestArgs{"testdata/sources/duplicate.pkr.hcl", nil}, + parseTestArgs{"testdata/sources/duplicate.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "sources"), Sources: map[SourceRef]*SourceBlock{ diff --git a/hcl2template/types.variables_test.go b/hcl2template/types.variables_test.go index f6d22d219..e53ff02b6 100644 --- a/hcl2template/types.variables_test.go +++ b/hcl2template/types.variables_test.go @@ -20,7 +20,7 @@ func TestParse_variables(t *testing.T) { tests := []parseTest{ {"basic variables", defaultParser, - parseTestArgs{"testdata/variables/basic.pkr.hcl", nil}, + parseTestArgs{"testdata/variables/basic.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "variables"), InputVariables: Variables{ @@ -75,7 +75,7 @@ func TestParse_variables(t *testing.T) { }, {"duplicate variable", defaultParser, - parseTestArgs{"testdata/variables/duplicate_variable.pkr.hcl", nil}, + parseTestArgs{"testdata/variables/duplicate_variable.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "variables"), InputVariables: Variables{ @@ -90,7 +90,7 @@ func TestParse_variables(t *testing.T) { }, {"duplicate variable in variables", defaultParser, - parseTestArgs{"testdata/variables/duplicate_variables.pkr.hcl", nil}, + parseTestArgs{"testdata/variables/duplicate_variables.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "variables"), InputVariables: Variables{ @@ -105,7 +105,7 @@ func TestParse_variables(t *testing.T) { }, {"invalid default type", defaultParser, - parseTestArgs{"testdata/variables/invalid_default.pkr.hcl", nil}, + parseTestArgs{"testdata/variables/invalid_default.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "variables"), InputVariables: Variables{ @@ -121,7 +121,7 @@ func TestParse_variables(t *testing.T) { {"unknown key", defaultParser, - parseTestArgs{"testdata/variables/unknown_key.pkr.hcl", nil}, + parseTestArgs{"testdata/variables/unknown_key.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "variables"), InputVariables: Variables{ @@ -138,7 +138,7 @@ func TestParse_variables(t *testing.T) { {"unset used variable", defaultParser, - parseTestArgs{"testdata/variables/unset_used_string_variable.pkr.hcl", nil}, + parseTestArgs{"testdata/variables/unset_used_string_variable.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "variables"), InputVariables: Variables{ @@ -154,7 +154,7 @@ func TestParse_variables(t *testing.T) { {"unset unused variable", defaultParser, - parseTestArgs{"testdata/variables/unset_unused_string_variable.pkr.hcl", nil}, + parseTestArgs{"testdata/variables/unset_unused_string_variable.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "variables"), InputVariables: Variables{ @@ -189,7 +189,7 @@ func TestParse_variables(t *testing.T) { {"locals within another locals usage in different files", defaultParser, - parseTestArgs{"testdata/variables/complicated", nil}, + parseTestArgs{"testdata/variables/complicated", nil, nil}, &PackerConfig{ Basedir: "testdata/variables/complicated", InputVariables: Variables{ @@ -231,7 +231,7 @@ func TestParse_variables(t *testing.T) { }, {"recursive locals", defaultParser, - parseTestArgs{"testdata/variables/recursive_locals.pkr.hcl", nil}, + parseTestArgs{"testdata/variables/recursive_locals.pkr.hcl", nil, nil}, &PackerConfig{ Basedir: filepath.Join("testdata", "variables"), LocalVariables: Variables{}, diff --git a/helper/flag-kv/flag_strings.go b/helper/flag-kv/flag_strings.go new file mode 100644 index 000000000..2d63af9fa --- /dev/null +++ b/helper/flag-kv/flag_strings.go @@ -0,0 +1,16 @@ +package kvflag + +import ( + "strings" +) + +type StringSlice []string + +func (s *StringSlice) String() string { + return strings.Join(*s, ", ") +} + +func (s *StringSlice) Set(value string) error { + *s = append(*s, value) + return nil +} From 6b48feb81782fcb68003b922a77856ae871b212d Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Thu, 12 Mar 2020 16:28:23 +0100 Subject: [PATCH 16/41] kvflag: add TestStringSlice_Set --- helper/flag-kv/flag_strings_test.go | 32 +++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 helper/flag-kv/flag_strings_test.go diff --git a/helper/flag-kv/flag_strings_test.go b/helper/flag-kv/flag_strings_test.go new file mode 100644 index 000000000..bc6c3af18 --- /dev/null +++ b/helper/flag-kv/flag_strings_test.go @@ -0,0 +1,32 @@ +package kvflag + +import ( + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestStringSlice_Set(t *testing.T) { + type args struct { + values []string + } + tests := []struct { + name string + s StringSlice + args args + wantStringSlice StringSlice + }{ + {"basic", StringSlice{"hey", "yo"}, args{[]string{"how", "are", "you"}}, + StringSlice{"hey", "yo", "how", "are", "you"}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + for _, value := range tt.args.values { + tt.s.Set(value) + } + if diff := cmp.Diff(tt.s, tt.wantStringSlice); diff != "" { + t.Fatal(diff) + } + }) + } +} From 710ebdcef5deaf9724db0e92a308ea6be151f8ca Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Thu, 12 Mar 2020 17:08:53 +0100 Subject: [PATCH 17/41] add more test for var files --- hcl2template/common_test.go | 3 ++ .../variables/foo-string.variable.pkr.hcl | 4 +++ .../testdata/variables/set-foo-too-wee.hcl | 1 + hcl2template/types.variables_test.go | 29 +++++++++++++++++++ 4 files changed, 37 insertions(+) create mode 100644 hcl2template/testdata/variables/foo-string.variable.pkr.hcl create mode 100644 hcl2template/testdata/variables/set-foo-too-wee.hcl diff --git a/hcl2template/common_test.go b/hcl2template/common_test.go index fd472cf3b..a49814174 100644 --- a/hcl2template/common_test.go +++ b/hcl2template/common_test.go @@ -91,6 +91,9 @@ func testParse(t *testing.T, tests []parseTest) { if variable.DefaultValue.GoString() != value.DefaultValue.GoString() { t.Fatalf("Parser.parse() input variable %s expected '%s' but was '%s'", name, value.DefaultValue.GoString(), variable.DefaultValue.GoString()) } + if diff := cmp.Diff(variable.VarfileValue.GoString(), value.VarfileValue.GoString()); diff != "" { + t.Fatalf("Parser.parse(): varfile value differs: %s", diff) + } } else { t.Fatalf("Parser.parse() missing input variable. %s", name) } diff --git a/hcl2template/testdata/variables/foo-string.variable.pkr.hcl b/hcl2template/testdata/variables/foo-string.variable.pkr.hcl new file mode 100644 index 000000000..931ab5431 --- /dev/null +++ b/hcl2template/testdata/variables/foo-string.variable.pkr.hcl @@ -0,0 +1,4 @@ +variable "foo" { + type = string + default = "bar" +} diff --git a/hcl2template/testdata/variables/set-foo-too-wee.hcl b/hcl2template/testdata/variables/set-foo-too-wee.hcl new file mode 100644 index 000000000..5e643a49b --- /dev/null +++ b/hcl2template/testdata/variables/set-foo-too-wee.hcl @@ -0,0 +1 @@ +foo = "wee" diff --git a/hcl2template/types.variables_test.go b/hcl2template/types.variables_test.go index e53ff02b6..15f5fc9f6 100644 --- a/hcl2template/types.variables_test.go +++ b/hcl2template/types.variables_test.go @@ -240,6 +240,35 @@ func TestParse_variables(t *testing.T) { []packer.Build{}, false, }, + + {"set variable from var-file", + defaultParser, + parseTestArgs{"testdata/variables/foo-string.variable.pkr.hcl", nil, []string{"testdata/variables/set-foo-too-wee.hcl"}}, + &PackerConfig{ + Basedir: filepath.Join("testdata", "variables"), + InputVariables: Variables{ + "foo": &Variable{ + DefaultValue: cty.StringVal("bar"), + Name: "foo", + VarfileValue: cty.StringVal("wee"), + }, + }, + }, + false, false, + []packer.Build{}, + false, + }, + + {"unknown variable from var-file", + defaultParser, + parseTestArgs{"testdata/variables/empty.pkr.hcl", nil, []string{"testdata/variables/set-foo-too-wee.hcl"}}, + &PackerConfig{ + Basedir: filepath.Join("testdata", "variables"), + }, + true, false, + []packer.Build{}, + false, + }, } testParse(t, tests) } From ad5495ac8f7f625b91e7d7d0cef5c0ae12c20507 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 12 Mar 2020 09:50:02 -0700 Subject: [PATCH 18/41] Update packer/core.go Co-Authored-By: Adrien Delorme --- packer/core.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packer/core.go b/packer/core.go index 16780d086..f52becab3 100644 --- a/packer/core.go +++ b/packer/core.go @@ -350,7 +350,7 @@ func (c *Core) validate() error { func isDoneInterpolating(v string) (bool, error) { // Check for whether the var contains any more references to `user`, wrapped // in interpolation syntax. - filter := "{{\\s*|user\\s*|\\x60?.*\\x60?}}" + filter := `{{\s*|user\s*|\x60?.*\x60?}}` matched, err := regexp.MatchString(filter, v) if err != nil { return false, fmt.Errorf("Can't tell if interpolation is done: %s", err) From a3740bb9be69a8665dd4849797cc47bc56a25197 Mon Sep 17 00:00:00 2001 From: Moss Date: Thu, 12 Mar 2020 17:54:31 +0100 Subject: [PATCH 19/41] Interpolate shell inline config --- provisioner/shell/provisioner.go | 28 ++++++++++++++++------------ template.json | 29 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 template.json diff --git a/provisioner/shell/provisioner.go b/provisioner/shell/provisioner.go index 3828c07b4..38ab4c474 100644 --- a/provisioner/shell/provisioner.go +++ b/provisioner/shell/provisioner.go @@ -70,12 +70,6 @@ type Provisioner struct { config Config } -type ExecuteCommandTemplate struct { - Vars string - EnvVarFile string - Path string -} - func (p *Provisioner) ConfigSpec() hcldec.ObjectSpec { return p.config.FlatMapstructure().HCL2Spec() } func (p *Provisioner) Prepare(raws ...interface{}) error { @@ -181,7 +175,11 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { return nil } -func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.Communicator, _ map[string]interface{}) error { +func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.Communicator, generatedData map[string]interface{}) error { + if generatedData == nil { + generatedData = make(map[string]interface{}) + } + scripts := make([]string, len(p.config.Scripts)) copy(scripts, p.config.Scripts) @@ -201,6 +199,11 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C writer := bufio.NewWriter(tf) writer.WriteString(fmt.Sprintf("#!%s\n", p.config.InlineShebang)) for _, command := range p.config.Inline { + p.config.ctx.Data = generatedData + command, err := interpolate.Render(command, &p.config.ctx); + if err != nil { + return fmt.Errorf("Error interpolating Inline: %s", err) + } if _, err := writer.WriteString(command + "\n"); err != nil { return fmt.Errorf("Error preparing shell script: %s", err) } @@ -279,11 +282,12 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C defer f.Close() // Compile the command - p.config.ctx.Data = &ExecuteCommandTemplate{ - Vars: flattenedEnvVars, - EnvVarFile: p.config.envVarFile, - Path: p.config.RemotePath, - } + // These are extra variables that will be made available for interpolation. + generatedData["Vars"] = flattenedEnvVars + generatedData["EnvVarFile"] = p.config.envVarFile + generatedData["Path"] = p.config.RemotePath + p.config.ctx.Data = generatedData + command, err := interpolate.Render(p.config.ExecuteCommand, &p.config.ctx) if err != nil { return fmt.Errorf("Error processing command: %s", err) diff --git a/template.json b/template.json new file mode 100644 index 000000000..fff4778a5 --- /dev/null +++ b/template.json @@ -0,0 +1,29 @@ +{ + "builders": [ + { + "type": "amazon-ebs", + "ami_name": "moss-packer-whee", + "instance_type": "t2.micro", + "source_ami_filter": { + "filters": { + "virtualization-type": "hvm", + "name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*", + "root-device-type": "ebs" + }, + "owners": ["099720109477"], + "most_recent": true + }, + "ssh_username": "ubuntu" + } + ], + "provisioners": [ + { + "type": "shell-local", + "inline": ["echo MOSS packer run uuid is '{{ build `PackerRunUUID`}}'"] + }, + { + "type": "shell", + "inline": ["echo MOSS packer run uuid is '{{ build `PackerRunUUID`}}'"] + } + ] +} From ebdc694b250ffc38f042cf546c517c62f355faab Mon Sep 17 00:00:00 2001 From: Moss Date: Thu, 12 Mar 2020 17:58:11 +0100 Subject: [PATCH 20/41] Remove template.json --- template.json | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 template.json diff --git a/template.json b/template.json deleted file mode 100644 index fff4778a5..000000000 --- a/template.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "builders": [ - { - "type": "amazon-ebs", - "ami_name": "moss-packer-whee", - "instance_type": "t2.micro", - "source_ami_filter": { - "filters": { - "virtualization-type": "hvm", - "name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*", - "root-device-type": "ebs" - }, - "owners": ["099720109477"], - "most_recent": true - }, - "ssh_username": "ubuntu" - } - ], - "provisioners": [ - { - "type": "shell-local", - "inline": ["echo MOSS packer run uuid is '{{ build `PackerRunUUID`}}'"] - }, - { - "type": "shell", - "inline": ["echo MOSS packer run uuid is '{{ build `PackerRunUUID`}}'"] - } - ] -} From 6c06a2a0485f959d86d9a623f53eba8fb480bbad Mon Sep 17 00:00:00 2001 From: Moss Date: Thu, 12 Mar 2020 17:59:34 +0100 Subject: [PATCH 21/41] Fix format --- provisioner/shell/provisioner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/shell/provisioner.go b/provisioner/shell/provisioner.go index 38ab4c474..6035c5e97 100644 --- a/provisioner/shell/provisioner.go +++ b/provisioner/shell/provisioner.go @@ -200,7 +200,7 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C writer.WriteString(fmt.Sprintf("#!%s\n", p.config.InlineShebang)) for _, command := range p.config.Inline { p.config.ctx.Data = generatedData - command, err := interpolate.Render(command, &p.config.ctx); + command, err := interpolate.Render(command, &p.config.ctx) if err != nil { return fmt.Errorf("Error interpolating Inline: %s", err) } From 17f59c4ddce4ecc8331667997652e4f0bd55dcd4 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 12 Mar 2020 10:00:56 -0700 Subject: [PATCH 22/41] fix regex and actually test the check function --- packer/core.go | 2 +- packer/core_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packer/core.go b/packer/core.go index f52becab3..b8682d159 100644 --- a/packer/core.go +++ b/packer/core.go @@ -350,7 +350,7 @@ func (c *Core) validate() error { func isDoneInterpolating(v string) (bool, error) { // Check for whether the var contains any more references to `user`, wrapped // in interpolation syntax. - filter := `{{\s*|user\s*|\x60?.*\x60?}}` + filter := `{{\s*user\s*\x60.*\x60\s*}}` matched, err := regexp.MatchString(filter, v) if err != nil { return false, fmt.Errorf("Can't tell if interpolation is done: %s", err) diff --git a/packer/core_test.go b/packer/core_test.go index e2bfb86d7..8982afbb2 100644 --- a/packer/core_test.go +++ b/packer/core_test.go @@ -679,7 +679,7 @@ func TestSensitiveVars(t *testing.T) { } // Normally I wouldn't test a little helper function, but it's regex. -func testisDoneInterpolating(t *testing.T) { +func TestIsDoneInterpolating(t *testing.T) { cases := []struct { inputString string expectedBool bool From 7ec39ebb4ea30c2c6a203118cad5d9225e0d48da Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Thu, 12 Mar 2020 18:01:20 +0100 Subject: [PATCH 23/41] TestStringSlice_Set: check error even if none is returned --- helper/flag-kv/flag_strings_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/helper/flag-kv/flag_strings_test.go b/helper/flag-kv/flag_strings_test.go index bc6c3af18..48de4bb18 100644 --- a/helper/flag-kv/flag_strings_test.go +++ b/helper/flag-kv/flag_strings_test.go @@ -22,7 +22,10 @@ func TestStringSlice_Set(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { for _, value := range tt.args.values { - tt.s.Set(value) + err := tt.s.Set(value) + if err != nil { + t.Fatal(err) + } } if diff := cmp.Diff(tt.s, tt.wantStringSlice); diff != "" { t.Fatal(diff) From c9ec96720551b4aed1f297d12d8ed3f341f551bb Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Thu, 12 Mar 2020 18:01:25 +0100 Subject: [PATCH 24/41] better testing --- hcl2template/common_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hcl2template/common_test.go b/hcl2template/common_test.go index a49814174..ff2a94946 100644 --- a/hcl2template/common_test.go +++ b/hcl2template/common_test.go @@ -88,11 +88,11 @@ func testParse(t *testing.T, tests []parseTest) { gotInputVar := gotCfg.InputVariables for name, value := range tt.parseWantCfg.InputVariables { if variable, ok := gotInputVar[name]; ok { - if variable.DefaultValue.GoString() != value.DefaultValue.GoString() { - t.Fatalf("Parser.parse() input variable %s expected '%s' but was '%s'", name, value.DefaultValue.GoString(), variable.DefaultValue.GoString()) + if diff := cmp.Diff(variable.DefaultValue.GoString(), value.DefaultValue.GoString()); diff != "" { + t.Fatalf("Parser.parse(): unexpected default value for %s: %s", name, diff) } if diff := cmp.Diff(variable.VarfileValue.GoString(), value.VarfileValue.GoString()); diff != "" { - t.Fatalf("Parser.parse(): varfile value differs: %s", diff) + t.Fatalf("Parser.parse(): varfile value differs for %s: %s", name, diff) } } else { t.Fatalf("Parser.parse() missing input variable. %s", name) From 32595f71cfb2d989521c44d6a335bc70b32719de Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Thu, 12 Mar 2020 13:40:56 -0700 Subject: [PATCH 25/41] sort interpolation input to make the interpolation deterministic --- packer/core.go | 46 ++++++++++++++++++++++---- packer/core_test.go | 79 ++++++++++++++++++++++----------------------- 2 files changed, 78 insertions(+), 47 deletions(-) diff --git a/packer/core.go b/packer/core.go index b8682d159..5d7337e61 100644 --- a/packer/core.go +++ b/packer/core.go @@ -2,6 +2,7 @@ package packer import ( "fmt" + "log" "regexp" "sort" "strings" @@ -399,14 +400,29 @@ func (c *Core) renderVarsRecursively() (*interpolate.Context, error) { // out the appropriate interpolations. repeatMap := make(map[string]string) + allKeys := make([]string, 0) + // load in template variables for k, v := range c.Template.Variables { repeatMap[k] = v.Default + allKeys = append(allKeys, k) } // overwrite template variables with command-line-read variables for k, v := range c.variables { repeatMap[k] = v + allKeys = append(allKeys, k) + } + + // sort map to force the following loop to be deterministic. + sort.Strings(allKeys) + type keyValue struct { + Key string + Value string + } + sortedMap := make([]keyValue, len(repeatMap)) + for _, k := range allKeys { + sortedMap = append(sortedMap, keyValue{k, repeatMap[k]}) } // Regex to exclude any build function variable or template variable @@ -416,25 +432,27 @@ func (c *Core) renderVarsRecursively() (*interpolate.Context, error) { for i := 0; i < 100; i++ { shouldRetry = false + changed = false + deleteKeys := []string{} // First, loop over the variables in the template - for k, v := range repeatMap { + for _, kv := range sortedMap { // Interpolate the default - renderedV, err := interpolate.RenderRegex(v, ctx, renderFilter) + renderedV, err := interpolate.RenderRegex(kv.Value, ctx, renderFilter) switch err.(type) { case nil: // We only get here if interpolation has succeeded, so something is // different in this loop than in the last one. changed = true - c.variables[k] = renderedV + c.variables[kv.Key] = renderedV ctx.UserVariables = c.variables // Remove fully-interpolated variables from the map, and flag // variables that still need interpolating for a repeat. - done, err := isDoneInterpolating(v) + done, err := isDoneInterpolating(kv.Value) if err != nil { return ctx, err } if done { - delete(repeatMap, k) + deleteKeys = append(deleteKeys, kv.Key) } else { shouldRetry = true } @@ -442,7 +460,7 @@ func (c *Core) renderVarsRecursively() (*interpolate.Context, error) { castError := err.(ttmp.ExecError) if strings.Contains(castError.Error(), interpolate.ErrVariableNotSetString) { shouldRetry = true - failedInterpolation = fmt.Sprintf(`"%s": "%s"; error: %s`, k, v, err) + failedInterpolation = fmt.Sprintf(`"%s": "%s"; error: %s`, kv.Key, kv.Value, err) } else { return ctx, err } @@ -450,12 +468,26 @@ func (c *Core) renderVarsRecursively() (*interpolate.Context, error) { return ctx, fmt.Errorf( // unexpected interpolation error: abort the run "error interpolating default value for '%s': %s", - k, err) + kv.Key, err) } } if !shouldRetry { break } + + // Clear completed vars from sortedMap before next loop. Do this one + // key at a time because the indices are gonna change ever time you + // delete from the map. + for _, k := range deleteKeys { + for ind, kv := range sortedMap { + if kv.Key == k { + log.Printf("Deleting kv.Value: %s", kv.Value) + sortedMap = append(sortedMap[:ind], sortedMap[ind+1:]...) + break + } + } + } + deleteKeys = []string{} } if !changed && shouldRetry { diff --git a/packer/core_test.go b/packer/core_test.go index 8982afbb2..17d76eb0c 100644 --- a/packer/core_test.go +++ b/packer/core_test.go @@ -540,7 +540,12 @@ func TestCore_InterpolateUserVars(t *testing.T) { }) if (err != nil) != tc.Err { - t.Fatalf("err: %s\n\n%s", tc.File, err) + if tc.Err == false { + t.Fatalf("Error interpolating %s: Expected no error, but got: %s", tc.File, err) + } else { + t.Fatalf("Error interpolating %s: Expected an error, but got: %s", tc.File, err) + } + } if !tc.Err { for k, v := range ccf.variables { @@ -727,49 +732,43 @@ func TestEnvAndFileVars(t *testing.T) { os.Setenv("INTERPOLATE_TEST_ENV_2", "5") os.Setenv("INTERPOLATE_TEST_ENV_4", "bananas") - // run the interpolations a bunch of times, because we have had issues - // where the behavior is different based on the order in which the - // vars are interpolated - for i := 0; i < 100; i++ { - f, err := os.Open(fixtureDir("complex-recursed-env-user-var-file.json")) - if err != nil { - t.Fatalf("err: %s", err) - } + f, err := os.Open(fixtureDir("complex-recursed-env-user-var-file.json")) + if err != nil { + t.Fatalf("err: %s", err) + } - tpl, err := template.Parse(f) - f.Close() - if err != nil { - t.Fatalf("err: %s\n\n%s", "complex-recursed-env-user-var-file.json", err) - } + tpl, err := template.Parse(f) + f.Close() + if err != nil { + t.Fatalf("err: %s\n\n%s", "complex-recursed-env-user-var-file.json", err) + } - ccf, err := NewCore(&CoreConfig{ - Template: tpl, - Version: "1.0.0", - Variables: map[string]string{ - "var_1": "partyparrot", - "var_2": "{{user `env_1`}}-{{user `env_2`}}{{user `env_3`}}-{{user `var_1`}}", - "final_var": "{{user `env_1`}}/{{user `env_2`}}/{{user `env_4`}}{{user `env_3`}}-{{user `var_1`}}/vmware/{{user `var_2`}}.vmx", - }, - }) - expected := map[string]string{ + ccf, err := NewCore(&CoreConfig{ + Template: tpl, + Version: "1.0.0", + Variables: map[string]string{ "var_1": "partyparrot", - "var_2": "bulbasaur-5/path/to/nowhere-partyparrot", - "final_var": "bulbasaur/5/bananas/path/to/nowhere-partyparrot/vmware/bulbasaur-5/path/to/nowhere-partyparrot.vmx", - "env_1": "bulbasaur", - "env_2": "5", - "env_3": "/path/to/nowhere", - "env_4": "bananas", + "var_2": "{{user `env_1`}}-{{user `env_2`}}{{user `env_3`}}-{{user `var_1`}}", + "final_var": "{{user `env_1`}}/{{user `env_2`}}/{{user `env_4`}}{{user `env_3`}}-{{user `var_1`}}/vmware/{{user `var_2`}}.vmx", + }, + }) + expected := map[string]string{ + "var_1": "partyparrot", + "var_2": "bulbasaur-5/path/to/nowhere-partyparrot", + "final_var": "bulbasaur/5/bananas/path/to/nowhere-partyparrot/vmware/bulbasaur-5/path/to/nowhere-partyparrot.vmx", + "env_1": "bulbasaur", + "env_2": "5", + "env_3": "/path/to/nowhere", + "env_4": "bananas", + } + if err != nil { + t.Fatalf("err: %s\n\n%s", "complex-recursed-env-user-var-file.json", err) + } + for k, v := range ccf.variables { + if expected[k] != v { + t.Fatalf("Expected value %s for key %s but got %s", + expected[k], k, v) } - if err != nil { - t.Fatalf("err: %s\n\n%s", "complex-recursed-env-user-var-file.json", err) - } - for k, v := range ccf.variables { - if expected[k] != v { - t.Fatalf("Expected value %s for key %s but got %s", - expected[k], k, v) - } - } - } // Clean up env vars From 4787455796002307f4284c13b392efdbe0c4e3a2 Mon Sep 17 00:00:00 2001 From: r_takaishi Date: Fri, 13 Mar 2020 11:22:13 +0900 Subject: [PATCH 26/41] fix lint --- communicator/ssh/keyboard_interactive.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/communicator/ssh/keyboard_interactive.go b/communicator/ssh/keyboard_interactive.go index 5f1013bd3..4da16d733 100644 --- a/communicator/ssh/keyboard_interactive.go +++ b/communicator/ssh/keyboard_interactive.go @@ -1,10 +1,11 @@ package ssh import ( - "golang.org/x/crypto/ssh" - "golang.org/x/crypto/ssh/terminal" "log" "os" + + "golang.org/x/crypto/ssh" + "golang.org/x/crypto/ssh/terminal" ) func KeyboardInteractive() ssh.KeyboardInteractiveChallenge { From f50ff1d270f383855cdefe0190006f0a9a096147 Mon Sep 17 00:00:00 2001 From: r_takaishi Date: Fri, 13 Mar 2020 11:29:42 +0900 Subject: [PATCH 27/41] make generate --- builder/alicloud/ecs/builder.hcl2spec.go | 2 ++ builder/amazon/ebs/builder.hcl2spec.go | 2 ++ builder/amazon/ebssurrogate/builder.hcl2spec.go | 2 ++ builder/amazon/ebsvolume/builder.hcl2spec.go | 2 ++ builder/amazon/instance/builder.hcl2spec.go | 2 ++ builder/azure/arm/config.hcl2spec.go | 2 ++ builder/cloudstack/config.hcl2spec.go | 2 ++ builder/digitalocean/config.hcl2spec.go | 2 ++ builder/docker/config.hcl2spec.go | 2 ++ builder/googlecompute/config.hcl2spec.go | 2 ++ builder/hcloud/config.hcl2spec.go | 2 ++ builder/hyperone/config.hcl2spec.go | 2 ++ builder/hyperv/iso/builder.hcl2spec.go | 2 ++ builder/hyperv/vmcx/builder.hcl2spec.go | 2 ++ builder/jdcloud/common.hcl2spec.go | 2 ++ builder/linode/config.hcl2spec.go | 2 ++ builder/ncloud/config.hcl2spec.go | 2 ++ builder/null/config.hcl2spec.go | 2 ++ builder/oneandone/config.hcl2spec.go | 2 ++ builder/openstack/builder.hcl2spec.go | 2 ++ builder/oracle/classic/builder.hcl2spec.go | 2 ++ builder/oracle/oci/config.hcl2spec.go | 2 ++ builder/osc/bsu/builder.hcl2spec.go | 2 ++ builder/osc/bsusurrogate/builder.hcl2spec.go | 2 ++ builder/osc/bsuvolume/builder.hcl2spec.go | 2 ++ builder/parallels/iso/builder.hcl2spec.go | 2 ++ builder/parallels/pvm/config.hcl2spec.go | 2 ++ builder/profitbricks/config.hcl2spec.go | 2 ++ builder/proxmox/config.hcl2spec.go | 2 ++ builder/qemu/builder.hcl2spec.go | 2 ++ builder/scaleway/config.hcl2spec.go | 2 ++ builder/tencentcloud/cvm/builder.hcl2spec.go | 2 ++ builder/triton/config.hcl2spec.go | 2 ++ builder/ucloud/uhost/builder.hcl2spec.go | 2 ++ builder/vagrant/builder.hcl2spec.go | 2 ++ builder/virtualbox/iso/builder.hcl2spec.go | 2 ++ builder/virtualbox/ovf/config.hcl2spec.go | 2 ++ builder/virtualbox/vm/config.hcl2spec.go | 2 ++ builder/vmware/iso/config.hcl2spec.go | 2 ++ builder/vmware/vmx/config.hcl2spec.go | 2 ++ builder/vsphere/clone/config.hcl2spec.go | 2 ++ builder/vsphere/iso/config.hcl2spec.go | 2 ++ builder/yandex/config.hcl2spec.go | 2 ++ helper/communicator/config.hcl2spec.go | 4 ++++ post-processor/alicloud-import/post-processor.hcl2spec.go | 2 ++ 45 files changed, 92 insertions(+) diff --git a/builder/alicloud/ecs/builder.hcl2spec.go b/builder/alicloud/ecs/builder.hcl2spec.go index 2f5171f57..0fa1e5fe6 100644 --- a/builder/alicloud/ecs/builder.hcl2spec.go +++ b/builder/alicloud/ecs/builder.hcl2spec.go @@ -117,6 +117,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -223,6 +224,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/amazon/ebs/builder.hcl2spec.go b/builder/amazon/ebs/builder.hcl2spec.go index c447e5717..c78b9b290 100644 --- a/builder/amazon/ebs/builder.hcl2spec.go +++ b/builder/amazon/ebs/builder.hcl2spec.go @@ -98,6 +98,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -225,6 +226,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/amazon/ebssurrogate/builder.hcl2spec.go b/builder/amazon/ebssurrogate/builder.hcl2spec.go index 45b5f6548..93817d55b 100644 --- a/builder/amazon/ebssurrogate/builder.hcl2spec.go +++ b/builder/amazon/ebssurrogate/builder.hcl2spec.go @@ -122,6 +122,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -250,6 +251,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/amazon/ebsvolume/builder.hcl2spec.go b/builder/amazon/ebsvolume/builder.hcl2spec.go index 5f2467101..44804fd87 100644 --- a/builder/amazon/ebsvolume/builder.hcl2spec.go +++ b/builder/amazon/ebsvolume/builder.hcl2spec.go @@ -122,6 +122,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -230,6 +231,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/amazon/instance/builder.hcl2spec.go b/builder/amazon/instance/builder.hcl2spec.go index 388b28432..ffa9d2077 100644 --- a/builder/amazon/instance/builder.hcl2spec.go +++ b/builder/amazon/instance/builder.hcl2spec.go @@ -98,6 +98,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -232,6 +233,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/azure/arm/config.hcl2spec.go b/builder/azure/arm/config.hcl2spec.go index 0d116c42c..1e3266bff 100644 --- a/builder/azure/arm/config.hcl2spec.go +++ b/builder/azure/arm/config.hcl2spec.go @@ -86,6 +86,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -198,6 +199,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/cloudstack/config.hcl2spec.go b/builder/cloudstack/config.hcl2spec.go index 79839316b..9acba4001 100644 --- a/builder/cloudstack/config.hcl2spec.go +++ b/builder/cloudstack/config.hcl2spec.go @@ -39,6 +39,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -143,6 +144,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/digitalocean/config.hcl2spec.go b/builder/digitalocean/config.hcl2spec.go index a6f895ac7..6a71738a4 100644 --- a/builder/digitalocean/config.hcl2spec.go +++ b/builder/digitalocean/config.hcl2spec.go @@ -36,6 +36,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -113,6 +114,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/docker/config.hcl2spec.go b/builder/docker/config.hcl2spec.go index 9183f7770..69d2e5d3b 100644 --- a/builder/docker/config.hcl2spec.go +++ b/builder/docker/config.hcl2spec.go @@ -36,6 +36,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -122,6 +123,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/googlecompute/config.hcl2spec.go b/builder/googlecompute/config.hcl2spec.go index acc64f1c9..956c8e587 100644 --- a/builder/googlecompute/config.hcl2spec.go +++ b/builder/googlecompute/config.hcl2spec.go @@ -36,6 +36,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -136,6 +137,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/hcloud/config.hcl2spec.go b/builder/hcloud/config.hcl2spec.go index cf1ff3186..d19f2eadf 100644 --- a/builder/hcloud/config.hcl2spec.go +++ b/builder/hcloud/config.hcl2spec.go @@ -36,6 +36,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -111,6 +112,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/hyperone/config.hcl2spec.go b/builder/hyperone/config.hcl2spec.go index 849e3080d..ed69c7f0f 100644 --- a/builder/hyperone/config.hcl2spec.go +++ b/builder/hyperone/config.hcl2spec.go @@ -36,6 +36,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -130,6 +131,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/hyperv/iso/builder.hcl2spec.go b/builder/hyperv/iso/builder.hcl2spec.go index a7f2b18aa..73a85e32f 100644 --- a/builder/hyperv/iso/builder.hcl2spec.go +++ b/builder/hyperv/iso/builder.hcl2spec.go @@ -50,6 +50,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -159,6 +160,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/hyperv/vmcx/builder.hcl2spec.go b/builder/hyperv/vmcx/builder.hcl2spec.go index 113cd677e..d3c24363a 100644 --- a/builder/hyperv/vmcx/builder.hcl2spec.go +++ b/builder/hyperv/vmcx/builder.hcl2spec.go @@ -50,6 +50,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -161,6 +162,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/jdcloud/common.hcl2spec.go b/builder/jdcloud/common.hcl2spec.go index 486aeb51d..2e7cb1f0c 100644 --- a/builder/jdcloud/common.hcl2spec.go +++ b/builder/jdcloud/common.hcl2spec.go @@ -38,6 +38,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -112,6 +113,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/linode/config.hcl2spec.go b/builder/linode/config.hcl2spec.go index 5f9e8c8ed..75b04c2f6 100644 --- a/builder/linode/config.hcl2spec.go +++ b/builder/linode/config.hcl2spec.go @@ -36,6 +36,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -108,6 +109,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/ncloud/config.hcl2spec.go b/builder/ncloud/config.hcl2spec.go index 90559be6e..5923e0737 100644 --- a/builder/ncloud/config.hcl2spec.go +++ b/builder/ncloud/config.hcl2spec.go @@ -48,6 +48,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -121,6 +122,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/null/config.hcl2spec.go b/builder/null/config.hcl2spec.go index fb2f31145..af268a3d1 100644 --- a/builder/null/config.hcl2spec.go +++ b/builder/null/config.hcl2spec.go @@ -36,6 +36,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -97,6 +98,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/oneandone/config.hcl2spec.go b/builder/oneandone/config.hcl2spec.go index ed73682a2..5b69fd618 100644 --- a/builder/oneandone/config.hcl2spec.go +++ b/builder/oneandone/config.hcl2spec.go @@ -36,6 +36,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -105,6 +106,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/openstack/builder.hcl2spec.go b/builder/openstack/builder.hcl2spec.go index e15db51fa..d8460ab5f 100644 --- a/builder/openstack/builder.hcl2spec.go +++ b/builder/openstack/builder.hcl2spec.go @@ -63,6 +63,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -180,6 +181,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/oracle/classic/builder.hcl2spec.go b/builder/oracle/classic/builder.hcl2spec.go index d8bcf0079..5fb44dbf8 100644 --- a/builder/oracle/classic/builder.hcl2spec.go +++ b/builder/oracle/classic/builder.hcl2spec.go @@ -43,6 +43,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -124,6 +125,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/oracle/oci/config.hcl2spec.go b/builder/oracle/oci/config.hcl2spec.go index 107c1ae43..a41b0ceb7 100644 --- a/builder/oracle/oci/config.hcl2spec.go +++ b/builder/oracle/oci/config.hcl2spec.go @@ -36,6 +36,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -118,6 +119,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/osc/bsu/builder.hcl2spec.go b/builder/osc/bsu/builder.hcl2spec.go index 0883acd80..049241f50 100644 --- a/builder/osc/bsu/builder.hcl2spec.go +++ b/builder/osc/bsu/builder.hcl2spec.go @@ -88,6 +88,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -202,6 +203,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/osc/bsusurrogate/builder.hcl2spec.go b/builder/osc/bsusurrogate/builder.hcl2spec.go index 9b5370724..3dd48e982 100644 --- a/builder/osc/bsusurrogate/builder.hcl2spec.go +++ b/builder/osc/bsusurrogate/builder.hcl2spec.go @@ -73,6 +73,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -188,6 +189,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/osc/bsuvolume/builder.hcl2spec.go b/builder/osc/bsuvolume/builder.hcl2spec.go index 8c403743e..099af2270 100644 --- a/builder/osc/bsuvolume/builder.hcl2spec.go +++ b/builder/osc/bsuvolume/builder.hcl2spec.go @@ -112,6 +112,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -211,6 +212,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/parallels/iso/builder.hcl2spec.go b/builder/parallels/iso/builder.hcl2spec.go index 80e2eb76e..25cab9ca6 100644 --- a/builder/parallels/iso/builder.hcl2spec.go +++ b/builder/parallels/iso/builder.hcl2spec.go @@ -62,6 +62,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -160,6 +161,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/parallels/pvm/config.hcl2spec.go b/builder/parallels/pvm/config.hcl2spec.go index a3f0bbb11..d3ca6c6be 100644 --- a/builder/parallels/pvm/config.hcl2spec.go +++ b/builder/parallels/pvm/config.hcl2spec.go @@ -43,6 +43,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -124,6 +125,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/profitbricks/config.hcl2spec.go b/builder/profitbricks/config.hcl2spec.go index 1dc8dc7c1..fde2eb5bb 100644 --- a/builder/profitbricks/config.hcl2spec.go +++ b/builder/profitbricks/config.hcl2spec.go @@ -36,6 +36,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -109,6 +110,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/proxmox/config.hcl2spec.go b/builder/proxmox/config.hcl2spec.go index bdcf7d018..dc4a7dc39 100644 --- a/builder/proxmox/config.hcl2spec.go +++ b/builder/proxmox/config.hcl2spec.go @@ -50,6 +50,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -147,6 +148,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/qemu/builder.hcl2spec.go b/builder/qemu/builder.hcl2spec.go index 6e296846e..3a8f7936e 100644 --- a/builder/qemu/builder.hcl2spec.go +++ b/builder/qemu/builder.hcl2spec.go @@ -53,6 +53,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -168,6 +169,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/scaleway/config.hcl2spec.go b/builder/scaleway/config.hcl2spec.go index 89e5d85d5..02649ffe5 100644 --- a/builder/scaleway/config.hcl2spec.go +++ b/builder/scaleway/config.hcl2spec.go @@ -36,6 +36,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -109,6 +110,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/tencentcloud/cvm/builder.hcl2spec.go b/builder/tencentcloud/cvm/builder.hcl2spec.go index 97ef30c46..fd9a54748 100644 --- a/builder/tencentcloud/cvm/builder.hcl2spec.go +++ b/builder/tencentcloud/cvm/builder.hcl2spec.go @@ -71,6 +71,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -168,6 +169,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/triton/config.hcl2spec.go b/builder/triton/config.hcl2spec.go index 4f1b5a871..08641e906 100644 --- a/builder/triton/config.hcl2spec.go +++ b/builder/triton/config.hcl2spec.go @@ -57,6 +57,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -139,6 +140,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/ucloud/uhost/builder.hcl2spec.go b/builder/ucloud/uhost/builder.hcl2spec.go index 262a64271..822b749fa 100644 --- a/builder/ucloud/uhost/builder.hcl2spec.go +++ b/builder/ucloud/uhost/builder.hcl2spec.go @@ -54,6 +54,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -133,6 +134,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/vagrant/builder.hcl2spec.go b/builder/vagrant/builder.hcl2spec.go index 70aba5f49..75f53f844 100644 --- a/builder/vagrant/builder.hcl2spec.go +++ b/builder/vagrant/builder.hcl2spec.go @@ -52,6 +52,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -152,6 +153,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/virtualbox/iso/builder.hcl2spec.go b/builder/virtualbox/iso/builder.hcl2spec.go index fbd8342b6..ab15eb5b6 100644 --- a/builder/virtualbox/iso/builder.hcl2spec.go +++ b/builder/virtualbox/iso/builder.hcl2spec.go @@ -64,6 +64,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -184,6 +185,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/virtualbox/ovf/config.hcl2spec.go b/builder/virtualbox/ovf/config.hcl2spec.go index c8be73d84..b6745ee3a 100644 --- a/builder/virtualbox/ovf/config.hcl2spec.go +++ b/builder/virtualbox/ovf/config.hcl2spec.go @@ -52,6 +52,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -158,6 +159,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/virtualbox/vm/config.hcl2spec.go b/builder/virtualbox/vm/config.hcl2spec.go index 7e68db5ad..3dabbe647 100644 --- a/builder/virtualbox/vm/config.hcl2spec.go +++ b/builder/virtualbox/vm/config.hcl2spec.go @@ -52,6 +52,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -154,6 +155,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/vmware/iso/config.hcl2spec.go b/builder/vmware/iso/config.hcl2spec.go index 6a05a97ca..822c079e5 100644 --- a/builder/vmware/iso/config.hcl2spec.go +++ b/builder/vmware/iso/config.hcl2spec.go @@ -82,6 +82,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -212,6 +213,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/vmware/vmx/config.hcl2spec.go b/builder/vmware/vmx/config.hcl2spec.go index ba57cbdcd..2ba63b8ff 100644 --- a/builder/vmware/vmx/config.hcl2spec.go +++ b/builder/vmware/vmx/config.hcl2spec.go @@ -66,6 +66,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -172,6 +173,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/vsphere/clone/config.hcl2spec.go b/builder/vsphere/clone/config.hcl2spec.go index 992a83aa0..0b6f217d3 100644 --- a/builder/vsphere/clone/config.hcl2spec.go +++ b/builder/vsphere/clone/config.hcl2spec.go @@ -67,6 +67,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -163,6 +164,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/vsphere/iso/config.hcl2spec.go b/builder/vsphere/iso/config.hcl2spec.go index 6f1eeaeac..be7a1b6b7 100644 --- a/builder/vsphere/iso/config.hcl2spec.go +++ b/builder/vsphere/iso/config.hcl2spec.go @@ -94,6 +94,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -217,6 +218,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/builder/yandex/config.hcl2spec.go b/builder/yandex/config.hcl2spec.go index a3c10418b..a5ea41f02 100644 --- a/builder/yandex/config.hcl2spec.go +++ b/builder/yandex/config.hcl2spec.go @@ -36,6 +36,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -131,6 +132,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/helper/communicator/config.hcl2spec.go b/helper/communicator/config.hcl2spec.go index 977ac1d41..30a9beece 100644 --- a/helper/communicator/config.hcl2spec.go +++ b/helper/communicator/config.hcl2spec.go @@ -29,6 +29,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -83,6 +84,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, @@ -128,6 +130,7 @@ type FlatSSH struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -170,6 +173,7 @@ func (*FlatSSH) HCL2Spec() map[string]hcldec.Spec { "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_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}, diff --git a/post-processor/alicloud-import/post-processor.hcl2spec.go b/post-processor/alicloud-import/post-processor.hcl2spec.go index f0290a185..a070a6268 100644 --- a/post-processor/alicloud-import/post-processor.hcl2spec.go +++ b/post-processor/alicloud-import/post-processor.hcl2spec.go @@ -81,6 +81,7 @@ type FlatConfig struct { SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"` SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"` SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"` SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"` SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"` SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"` @@ -195,6 +196,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "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_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}, From 70e3f6053950b37358e57f2d7c4e80bfc747dafc Mon Sep 17 00:00:00 2001 From: r_takaishi Date: Fri, 13 Mar 2020 14:01:11 +0900 Subject: [PATCH 28/41] write unit test --- communicator/ssh/keyboard_interactive.go | 18 +--- communicator/ssh/keyboard_interactive_test.go | 89 +++++++++++++++++++ helper/communicator/step_connect_ssh.go | 15 +++- 3 files changed, 107 insertions(+), 15 deletions(-) create mode 100644 communicator/ssh/keyboard_interactive_test.go diff --git a/communicator/ssh/keyboard_interactive.go b/communicator/ssh/keyboard_interactive.go index 4da16d733..417ab00ae 100644 --- a/communicator/ssh/keyboard_interactive.go +++ b/communicator/ssh/keyboard_interactive.go @@ -1,14 +1,15 @@ package ssh import ( + "io" "log" - "os" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/terminal" ) -func KeyboardInteractive() ssh.KeyboardInteractiveChallenge { +func KeyboardInteractive(c io.ReadWriter) ssh.KeyboardInteractiveChallenge { + t := terminal.NewTerminal(c, "") return func(user, instruction string, questions []string, echos []bool) ([]string, error) { if len(questions) == 0 { return []string{}, nil @@ -21,18 +22,7 @@ func KeyboardInteractive() ssh.KeyboardInteractiveChallenge { } answers := make([]string, len(questions)) for i := range questions { - var fd int - if terminal.IsTerminal(int(os.Stdin.Fd())) { - fd = int(os.Stdin.Fd()) - } else { - tty, err := os.Open("/dev/tty") - if err != nil { - return nil, err - } - defer tty.Close() - fd = int(tty.Fd()) - } - s, err := terminal.ReadPassword(fd) + s, err := t.ReadPassword("") if err != nil { return nil, err } diff --git a/communicator/ssh/keyboard_interactive_test.go b/communicator/ssh/keyboard_interactive_test.go new file mode 100644 index 000000000..fc1bbfd45 --- /dev/null +++ b/communicator/ssh/keyboard_interactive_test.go @@ -0,0 +1,89 @@ +package ssh + +import ( + "io" + "log" + "reflect" + "testing" +) + +type MockTerminal struct { + toSend []byte + bytesPerRead int + received []byte +} + +func (c *MockTerminal) Read(data []byte) (n int, err error) { + n = len(data) + if n == 0 { + return + } + if n > len(c.toSend) { + n = len(c.toSend) + } + if n == 0 { + return 0, io.EOF + } + if c.bytesPerRead > 0 && n > c.bytesPerRead { + n = c.bytesPerRead + } + copy(data, c.toSend[:n]) + c.toSend = c.toSend[n:] + return +} + +func (c *MockTerminal) Write(data []byte) (n int, err error) { + c.received = append(c.received, data...) + return len(data), nil +} + +func TestKeyboardInteractive(t *testing.T) { + type args struct { + user string + instruction string + questions []string + echos []bool + } + tests := []struct { + name string + args args + want []string + wantErr bool + }{ + { + name: "questions are none", + args: args{ + questions: []string{}, + }, + want: []string{}, + wantErr: false, + }, + { + name: "input answer interactive", + args: args{ + questions: []string{"this is question"}, + }, + want: []string{"xxxx"}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &MockTerminal{ + toSend: []byte("xxxx\r\x1b[A\r"), + bytesPerRead: 1, + } + f := KeyboardInteractive(c) + got, err := f(tt.args.user, tt.args.instruction, tt.args.questions, tt.args.echos) + + if (err != nil) != tt.wantErr { + t.Errorf("KeyboardInteractive error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("KeyboardInteractive = %v, want %v", got, tt.want) + } + log.Printf("finish") + }) + } +} diff --git a/helper/communicator/step_connect_ssh.go b/helper/communicator/step_connect_ssh.go index 8eb1c5156..8ad82c23e 100644 --- a/helper/communicator/step_connect_ssh.go +++ b/helper/communicator/step_connect_ssh.go @@ -4,6 +4,8 @@ import ( "context" "errors" "fmt" + "golang.org/x/crypto/ssh/terminal" + "io" "log" "net" "os" @@ -247,7 +249,18 @@ func sshBastionConfig(config *Config) (*gossh.ClientConfig, error) { auth := make([]gossh.AuthMethod, 0, 2) if config.SSHBastionInteractive { - auth = append(auth, gossh.KeyboardInteractive(ssh.KeyboardInteractive())) + var c io.ReadWriteCloser + if terminal.IsTerminal(int(os.Stdin.Fd())) { + c = os.Stdin + } else { + tty, err := os.Open("/dev/tty") + if err != nil { + return nil, err + } + defer tty.Close() + c = tty + } + auth = append(auth, gossh.KeyboardInteractive(ssh.KeyboardInteractive(c))) } if config.SSHBastionPassword != "" { From 60a3105a4569bb05e2a7381e020790f46d71ab5e Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Fri, 13 Mar 2020 11:04:10 +0100 Subject: [PATCH 29/41] make ssh docs less AWS specific --- helper/communicator/config.go | 21 ++++++++----------- .../communicator/_SSH-not-required.html.md | 21 ++++++++----------- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/helper/communicator/config.go b/helper/communicator/config.go index fe992a1b0..9094d39a6 100644 --- a/helper/communicator/config.go +++ b/helper/communicator/config.go @@ -77,13 +77,12 @@ type SSH struct { // A plaintext password to use to authenticate with SSH. SSHPassword string `mapstructure:"ssh_password"` // If specified, this is the key that will be used for SSH with the - // machine. The key must match a key pair name loaded up into Amazon EC2. + // machine. The key must match a key pair name loaded up into the remote. // By default, this is blank, and Packer will generate a temporary keypair - // unless [`ssh_password`](../templates/communicator.html#ssh_password) is - // used. - // [`ssh_private_key_file`](../templates/communicator.html#ssh_private_key_file) - // or `ssh_agent_auth` must be specified when `ssh_keypair_name` is - // utilized. + // unless [`ssh_password`](#ssh_password) is used. + // [`ssh_private_key_file`](#ssh_private_key_file) or + // [`ssh_agent_auth`](#ssh_agent_auth) must be specified when + // [`ssh_keypair_name`](#ssh_keypair_name) is utilized. SSHKeyPairName string `mapstructure:"ssh_keypair_name"` // The name of the temporary key pair to generate. By default, Packer // generates a name that looks like `packer_`, where <UUID> is @@ -109,12 +108,10 @@ type SSH struct { SSHTimeout time.Duration `mapstructure:"ssh_timeout"` // If true, the local SSH agent will be used to authenticate connections to // the source instance. No temporary keypair will be created, and the - // values of `ssh_password` and `ssh_private_key_file` will be ignored. To - // use this option with a key pair already configured in the source AMI, - // leave the `ssh_keypair_name` blank. To associate an existing key pair in - // AWS with the source instance, set the `ssh_keypair_name` field to the - // name of the key pair. The environment variable `SSH_AUTH_SOCK` must be - // set for this option to work properly. + // values of [`ssh_password`](#ssh_password) and + // [`ssh_private_key_file`](#ssh_private_key_file) will be ignored. The + // environment variable `SSH_AUTH_SOCK` must be set for this option to work + // properly. SSHAgentAuth bool `mapstructure:"ssh_agent_auth"` // If true, SSH agent forwarding will be disabled. Defaults to `false`. SSHDisableAgentForwarding bool `mapstructure:"ssh_disable_agent_forwarding"` diff --git a/website/source/partials/helper/communicator/_SSH-not-required.html.md b/website/source/partials/helper/communicator/_SSH-not-required.html.md index 629654786..71616c0f3 100644 --- a/website/source/partials/helper/communicator/_SSH-not-required.html.md +++ b/website/source/partials/helper/communicator/_SSH-not-required.html.md @@ -10,13 +10,12 @@ - `ssh_password` (string) - A plaintext password to use to authenticate with SSH. - `ssh_keypair_name` (string) - If specified, this is the key that will be used for SSH with the - machine. The key must match a key pair name loaded up into Amazon EC2. + machine. The key must match a key pair name loaded up into the remote. By default, this is blank, and Packer will generate a temporary keypair - unless [`ssh_password`](../templates/communicator.html#ssh_password) is - used. - [`ssh_private_key_file`](../templates/communicator.html#ssh_private_key_file) - or `ssh_agent_auth` must be specified when `ssh_keypair_name` is - utilized. + unless [`ssh_password`](#ssh_password) is used. + [`ssh_private_key_file`](#ssh_private_key_file) or + [`ssh_agent_auth`](#ssh_agent_auth) must be specified when + [`ssh_keypair_name`](#ssh_keypair_name) is utilized. - `temporary_key_pair_name` (string) - The name of the temporary key pair to generate. By default, Packer generates a name that looks like `packer_`, where <UUID> is @@ -42,12 +41,10 @@ - `ssh_agent_auth` (bool) - If true, the local SSH agent will be used to authenticate connections to the source instance. No temporary keypair will be created, and the - values of `ssh_password` and `ssh_private_key_file` will be ignored. To - use this option with a key pair already configured in the source AMI, - leave the `ssh_keypair_name` blank. To associate an existing key pair in - AWS with the source instance, set the `ssh_keypair_name` field to the - name of the key pair. The environment variable `SSH_AUTH_SOCK` must be - set for this option to work properly. + values of [`ssh_password`](#ssh_password) and + [`ssh_private_key_file`](#ssh_private_key_file) will be ignored. The + environment variable `SSH_AUTH_SOCK` must be set for this option to work + properly. - `ssh_disable_agent_forwarding` (bool) - If true, SSH agent forwarding will be disabled. Defaults to `false`. From 7fbbbffd5c178e66c6ad2cbc7a0095a2e6e316ec Mon Sep 17 00:00:00 2001 From: Moss Date: Fri, 13 Mar 2020 16:17:40 +0100 Subject: [PATCH 30/41] Interpolate file provisioner and add integration tests --- provisioner/file/provisioner.go | 27 ++++++- test/helper/aws.go | 42 ++++++++++ test/provisioner/shell/provisioner_test.go | 78 +++++++++++++++++++ .../test-fixtures/shell-provisioner.json | 29 +++++++ 4 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 test/helper/aws.go create mode 100644 test/provisioner/shell/provisioner_test.go create mode 100644 test/provisioner/shell/test-fixtures/shell-provisioner.json diff --git a/provisioner/file/provisioner.go b/provisioner/file/provisioner.go index 7adf0197b..82e69570d 100644 --- a/provisioner/file/provisioner.go +++ b/provisioner/file/provisioner.go @@ -95,7 +95,12 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { return nil } -func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.Communicator, _ map[string]interface{}) error { +func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.Communicator, generatedData map[string]interface{}) error { + if generatedData == nil { + generatedData = make(map[string]interface{}) + } + p.config.ctx.Data = generatedData + if p.config.Direction == "download" { return p.ProvisionDownload(ui, comm) } else { @@ -105,7 +110,15 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C func (p *Provisioner) ProvisionDownload(ui packer.Ui, comm packer.Communicator) error { for _, src := range p.config.Sources { - dst := p.config.Destination + src, err := interpolate.Render(src, &p.config.ctx) + if err != nil { + return fmt.Errorf("Error interpolating source: %s", err) + } + dst, err := interpolate.Render(p.config.Destination, &p.config.ctx) + if err != nil { + return fmt.Errorf("Error interpolating destination: %s", err) + } + ui.Say(fmt.Sprintf("Downloading %s => %s", src, dst)) // ensure destination dir exists. p.config.Destination may either be a file or a dir. dir := dst @@ -146,7 +159,15 @@ func (p *Provisioner) ProvisionDownload(ui packer.Ui, comm packer.Communicator) func (p *Provisioner) ProvisionUpload(ui packer.Ui, comm packer.Communicator) error { for _, src := range p.config.Sources { - dst := p.config.Destination + src, err := interpolate.Render(src, &p.config.ctx) + if err != nil { + return fmt.Errorf("Error interpolating source: %s", err) + } + + dst, err := interpolate.Render(p.config.Destination, &p.config.ctx) + if err != nil { + return fmt.Errorf("Error interpolating destination: %s", err) + } ui.Say(fmt.Sprintf("Uploading %s => %s", src, dst)) diff --git a/test/helper/aws.go b/test/helper/aws.go new file mode 100644 index 000000000..df758b23d --- /dev/null +++ b/test/helper/aws.go @@ -0,0 +1,42 @@ +package helper + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + awscommon "github.com/hashicorp/packer/builder/amazon/common" + "testing" +) + +type AWSHelper struct { + Region string + AMIName string +} + +func (a *AWSHelper) CleanUpAmi(t *testing.T) { + accessConfig := &awscommon.AccessConfig{} + session, err := accessConfig.Session() + if err != nil { + t.Errorf("AWSAMICleanUp: Unable to create aws session %s", err.Error()) + } + + regionconn := ec2.New(session.Copy(&aws.Config{ + Region: aws.String(a.Region), + })) + + resp, err := regionconn.DescribeImages(&ec2.DescribeImagesInput{ + Owners: aws.StringSlice([]string{"self"}), + Filters: []*ec2.Filter{{ + Name: aws.String("name"), + Values: aws.StringSlice([]string{a.AMIName}), + }}}) + if err != nil { + t.Errorf("AWSAMICleanUp: Unable to find Image %s: %s",a.AMIName, err.Error()) + } + + _, err = regionconn.DeregisterImage(&ec2.DeregisterImageInput{ + ImageId: resp.Images[0].ImageId, + }) + if err != nil { + t.Errorf("AWSAMICleanUp: Unable to Deregister Image %s", err.Error()) + } +} \ No newline at end of file diff --git a/test/provisioner/shell/provisioner_test.go b/test/provisioner/shell/provisioner_test.go new file mode 100644 index 000000000..419acc77d --- /dev/null +++ b/test/provisioner/shell/provisioner_test.go @@ -0,0 +1,78 @@ +// +build integration + +package shell_integration + +import ( + "bytes" + "github.com/hashicorp/go-uuid" + amazonebsbuilder "github.com/hashicorp/packer/builder/amazon/ebs" + "github.com/hashicorp/packer/command" + "github.com/hashicorp/packer/packer" + fileprovisioner "github.com/hashicorp/packer/provisioner/file" + "github.com/hashicorp/packer/provisioner/shell" + testshelper "github.com/hashicorp/packer/test/helper" + "os" + "path/filepath" + "testing" +) + +func TestBuildShellProvisionerWithBuildVariablesSharing(t *testing.T) { + UUID, _ := uuid.GenerateUUID() + os.Setenv("PACKER_RUN_UUID", UUID) + c := &command.BuildCommand{ + Meta: testMetaFile(t), + } + + file := "provisioner.shell." + UUID + ".txt" + defer os.RemoveAll(file) + + args := []string{ + filepath.Join("./test-fixtures", "shell-provisioner.json"), + } + if code := c.Run(args); code != 0 { + ui := c.Meta.Ui.(*packer.BasicUi) + out := ui.Writer.(*bytes.Buffer) + err := ui.ErrorWriter.(*bytes.Buffer) + t.Fatalf( + "Bad exit code.\n\nStdout:\n\n%s\n\nStderr:\n\n%s", + out.String(), + err.String()) + } + + if _, err := os.Stat(file); err != nil { + t.Errorf("Expected to find %s", file) + } else { + helper := testshelper.AWSHelper{ + Region: "us-east-1", + AMIName: "packer-test-shell-interpolate", + } + helper.CleanUpAmi(t) + } +} + +func testMetaFile(t *testing.T) command.Meta { + var out, err bytes.Buffer + return command.Meta{ + CoreConfig: testCoreConfigBuilder(t), + Ui: &packer.BasicUi{ + Writer: &out, + ErrorWriter: &err, + }, + } +} + +func testCoreConfigBuilder(t *testing.T) *packer.CoreConfig { + components := packer.ComponentFinder{ + BuilderStore: packer.MapOfBuilder{ + "amazon-ebs": func() (packer.Builder, error) { return &amazonebsbuilder.Builder{}, nil }, + }, + ProvisionerStore: packer.MapOfProvisioner{ + "shell": func() (packer.Provisioner, error) { return &shell.Provisioner{}, nil }, + "file": func() (packer.Provisioner, error) { return &fileprovisioner.Provisioner{}, nil }, + }, + PostProcessorStore: packer.MapOfPostProcessor{}, + } + return &packer.CoreConfig{ + Components: components, + } +} diff --git a/test/provisioner/shell/test-fixtures/shell-provisioner.json b/test/provisioner/shell/test-fixtures/shell-provisioner.json new file mode 100644 index 000000000..df3604670 --- /dev/null +++ b/test/provisioner/shell/test-fixtures/shell-provisioner.json @@ -0,0 +1,29 @@ +{ + "builders": [ + { + "type": "amazon-ebs", + "ami_name": "packer-test-shell-interpolate", + "instance_type": "m1.small", + "region": "us-east-1", + "ssh_username": "ubuntu", + "source_ami": "ami-0568456c", + "tags": { + "packer-test": "true" + } + } + ], + "provisioners": [ + { + "type": "shell", + "inline": [ + "echo {{ build `ID`}} > provisioner.{{ build `PackerRunUUID`}}.txt" + ] + }, + { + "type": "file", + "source": "provisioner.{{ build `PackerRunUUID`}}.txt", + "destination": "provisioner.shell.{{ build `PackerRunUUID`}}.txt", + "direction": "download" + } + ] +} \ No newline at end of file From 2a7847a2ab0da0ec41b5c19579fa5609c790d502 Mon Sep 17 00:00:00 2001 From: Moss Date: Fri, 13 Mar 2020 16:35:31 +0100 Subject: [PATCH 31/41] Add integration tests helper on test package --- test/helper/core.go | 66 ++++++++++++++++++++++ test/provisioner/shell/provisioner_test.go | 45 ++------------- 2 files changed, 70 insertions(+), 41 deletions(-) create mode 100644 test/helper/core.go diff --git a/test/helper/core.go b/test/helper/core.go new file mode 100644 index 000000000..052610b0e --- /dev/null +++ b/test/helper/core.go @@ -0,0 +1,66 @@ +package helper + +import ( + "bytes" + amazonebsbuilder "github.com/hashicorp/packer/builder/amazon/ebs" + "github.com/hashicorp/packer/command" + "github.com/hashicorp/packer/packer" + fileprovisioner "github.com/hashicorp/packer/provisioner/file" + "github.com/hashicorp/packer/provisioner/shell" + "os" + "testing" +) + +// fileExists returns true if the filename is found +func FileExists(filename string) bool { + if _, err := os.Stat(filename); err == nil { + return true + } + return false +} + +// testCoreConfigBuilder creates a packer CoreConfig that has a file builder +// available. This allows us to test a builder that writes files to disk. +func testCoreConfigBuilder(t *testing.T) *packer.CoreConfig { + components := packer.ComponentFinder{ + BuilderStore: packer.MapOfBuilder{ + "amazon-ebs": func() (packer.Builder, error) { return &amazonebsbuilder.Builder{}, nil }, + }, + ProvisionerStore: packer.MapOfProvisioner{ + "shell": func() (packer.Provisioner, error) { return &shell.Provisioner{}, nil }, + "file": func() (packer.Provisioner, error) { return &fileprovisioner.Provisioner{}, nil }, + }, + PostProcessorStore: packer.MapOfPostProcessor{}, + } + return &packer.CoreConfig{ + Components: components, + } +} + +// TestMetaFile creates a Meta object that includes a file builder +func TestMetaFile(t *testing.T) command.Meta { + var out, err bytes.Buffer + return command.Meta{ + CoreConfig: testCoreConfigBuilder(t), + Ui: &packer.BasicUi{ + Writer: &out, + ErrorWriter: &err, + }, + } +} + +func CleanupFiles(moreFiles ...string) { + for _, file := range moreFiles { + os.RemoveAll(file) + } +} + +func FatalCommand(t *testing.T, m command.Meta) { + ui := m.Ui.(*packer.BasicUi) + out := ui.Writer.(*bytes.Buffer) + err := ui.ErrorWriter.(*bytes.Buffer) + t.Fatalf( + "Bad exit code.\n\nStdout:\n\n%s\n\nStderr:\n\n%s", + out.String(), + err.String()) +} \ No newline at end of file diff --git a/test/provisioner/shell/provisioner_test.go b/test/provisioner/shell/provisioner_test.go index 419acc77d..8cb801b90 100644 --- a/test/provisioner/shell/provisioner_test.go +++ b/test/provisioner/shell/provisioner_test.go @@ -3,13 +3,8 @@ package shell_integration import ( - "bytes" "github.com/hashicorp/go-uuid" - amazonebsbuilder "github.com/hashicorp/packer/builder/amazon/ebs" "github.com/hashicorp/packer/command" - "github.com/hashicorp/packer/packer" - fileprovisioner "github.com/hashicorp/packer/provisioner/file" - "github.com/hashicorp/packer/provisioner/shell" testshelper "github.com/hashicorp/packer/test/helper" "os" "path/filepath" @@ -20,26 +15,20 @@ func TestBuildShellProvisionerWithBuildVariablesSharing(t *testing.T) { UUID, _ := uuid.GenerateUUID() os.Setenv("PACKER_RUN_UUID", UUID) c := &command.BuildCommand{ - Meta: testMetaFile(t), + Meta: testshelper.TestMetaFile(t), } file := "provisioner.shell." + UUID + ".txt" - defer os.RemoveAll(file) + defer testshelper.CleanupFiles(file) args := []string{ filepath.Join("./test-fixtures", "shell-provisioner.json"), } if code := c.Run(args); code != 0 { - ui := c.Meta.Ui.(*packer.BasicUi) - out := ui.Writer.(*bytes.Buffer) - err := ui.ErrorWriter.(*bytes.Buffer) - t.Fatalf( - "Bad exit code.\n\nStdout:\n\n%s\n\nStderr:\n\n%s", - out.String(), - err.String()) + testshelper.FatalCommand(t, c.Meta) } - if _, err := os.Stat(file); err != nil { + if !testshelper.FileExists(file) { t.Errorf("Expected to find %s", file) } else { helper := testshelper.AWSHelper{ @@ -50,29 +39,3 @@ func TestBuildShellProvisionerWithBuildVariablesSharing(t *testing.T) { } } -func testMetaFile(t *testing.T) command.Meta { - var out, err bytes.Buffer - return command.Meta{ - CoreConfig: testCoreConfigBuilder(t), - Ui: &packer.BasicUi{ - Writer: &out, - ErrorWriter: &err, - }, - } -} - -func testCoreConfigBuilder(t *testing.T) *packer.CoreConfig { - components := packer.ComponentFinder{ - BuilderStore: packer.MapOfBuilder{ - "amazon-ebs": func() (packer.Builder, error) { return &amazonebsbuilder.Builder{}, nil }, - }, - ProvisionerStore: packer.MapOfProvisioner{ - "shell": func() (packer.Provisioner, error) { return &shell.Provisioner{}, nil }, - "file": func() (packer.Provisioner, error) { return &fileprovisioner.Provisioner{}, nil }, - }, - PostProcessorStore: packer.MapOfPostProcessor{}, - } - return &packer.CoreConfig{ - Components: components, - } -} From 449a299ee326e2be228d150929d280b42710a969 Mon Sep 17 00:00:00 2001 From: Moss Date: Fri, 13 Mar 2020 16:36:30 +0100 Subject: [PATCH 32/41] Fix format --- test/helper/aws.go | 6 +++--- test/helper/core.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/helper/aws.go b/test/helper/aws.go index df758b23d..76f27c8b1 100644 --- a/test/helper/aws.go +++ b/test/helper/aws.go @@ -8,7 +8,7 @@ import ( ) type AWSHelper struct { - Region string + Region string AMIName string } @@ -30,7 +30,7 @@ func (a *AWSHelper) CleanUpAmi(t *testing.T) { Values: aws.StringSlice([]string{a.AMIName}), }}}) if err != nil { - t.Errorf("AWSAMICleanUp: Unable to find Image %s: %s",a.AMIName, err.Error()) + t.Errorf("AWSAMICleanUp: Unable to find Image %s: %s", a.AMIName, err.Error()) } _, err = regionconn.DeregisterImage(&ec2.DeregisterImageInput{ @@ -39,4 +39,4 @@ func (a *AWSHelper) CleanUpAmi(t *testing.T) { if err != nil { t.Errorf("AWSAMICleanUp: Unable to Deregister Image %s", err.Error()) } -} \ No newline at end of file +} diff --git a/test/helper/core.go b/test/helper/core.go index 052610b0e..ca37a1119 100644 --- a/test/helper/core.go +++ b/test/helper/core.go @@ -27,8 +27,8 @@ func testCoreConfigBuilder(t *testing.T) *packer.CoreConfig { "amazon-ebs": func() (packer.Builder, error) { return &amazonebsbuilder.Builder{}, nil }, }, ProvisionerStore: packer.MapOfProvisioner{ - "shell": func() (packer.Provisioner, error) { return &shell.Provisioner{}, nil }, - "file": func() (packer.Provisioner, error) { return &fileprovisioner.Provisioner{}, nil }, + "shell": func() (packer.Provisioner, error) { return &shell.Provisioner{}, nil }, + "file": func() (packer.Provisioner, error) { return &fileprovisioner.Provisioner{}, nil }, }, PostProcessorStore: packer.MapOfPostProcessor{}, } @@ -63,4 +63,4 @@ func FatalCommand(t *testing.T, m command.Meta) { "Bad exit code.\n\nStdout:\n\n%s\n\nStderr:\n\n%s", out.String(), err.String()) -} \ No newline at end of file +} From 2ca680482779da44988ba6a0fb27373e995a8f90 Mon Sep 17 00:00:00 2001 From: Moss Date: Fri, 13 Mar 2020 17:10:51 +0100 Subject: [PATCH 33/41] Move shell prov acc test to the same folder --- {test/helper => helper/tests}/aws.go | 2 +- {test/helper => helper/tests}/core.go | 2 +- .../shell/provisioner_acc_test.go | 6 ++---- .../shell/test-fixtures/shell-provisioner.json | 0 4 files changed, 4 insertions(+), 6 deletions(-) rename {test/helper => helper/tests}/aws.go (98%) rename {test/helper => helper/tests}/core.go (98%) rename test/provisioner/shell/provisioner_test.go => provisioner/shell/provisioner_acc_test.go (88%) rename {test/provisioner => provisioner}/shell/test-fixtures/shell-provisioner.json (100%) diff --git a/test/helper/aws.go b/helper/tests/aws.go similarity index 98% rename from test/helper/aws.go rename to helper/tests/aws.go index 76f27c8b1..e579bcde1 100644 --- a/test/helper/aws.go +++ b/helper/tests/aws.go @@ -1,4 +1,4 @@ -package helper +package testshelper import ( "github.com/aws/aws-sdk-go/aws" diff --git a/test/helper/core.go b/helper/tests/core.go similarity index 98% rename from test/helper/core.go rename to helper/tests/core.go index ca37a1119..05af712de 100644 --- a/test/helper/core.go +++ b/helper/tests/core.go @@ -1,4 +1,4 @@ -package helper +package testshelper import ( "bytes" diff --git a/test/provisioner/shell/provisioner_test.go b/provisioner/shell/provisioner_acc_test.go similarity index 88% rename from test/provisioner/shell/provisioner_test.go rename to provisioner/shell/provisioner_acc_test.go index 8cb801b90..0c4d40301 100644 --- a/test/provisioner/shell/provisioner_test.go +++ b/provisioner/shell/provisioner_acc_test.go @@ -1,11 +1,9 @@ -// +build integration - -package shell_integration +package shell_test import ( "github.com/hashicorp/go-uuid" "github.com/hashicorp/packer/command" - testshelper "github.com/hashicorp/packer/test/helper" + "github.com/hashicorp/packer/helper/tests" "os" "path/filepath" "testing" diff --git a/test/provisioner/shell/test-fixtures/shell-provisioner.json b/provisioner/shell/test-fixtures/shell-provisioner.json similarity index 100% rename from test/provisioner/shell/test-fixtures/shell-provisioner.json rename to provisioner/shell/test-fixtures/shell-provisioner.json From 0cc1092222401f62ecb53669c4b377f8e6d5a66a Mon Sep 17 00:00:00 2001 From: Moss Date: Fri, 13 Mar 2020 17:11:13 +0100 Subject: [PATCH 34/41] Fix format --- provisioner/shell/provisioner_acc_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/provisioner/shell/provisioner_acc_test.go b/provisioner/shell/provisioner_acc_test.go index 0c4d40301..02508976d 100644 --- a/provisioner/shell/provisioner_acc_test.go +++ b/provisioner/shell/provisioner_acc_test.go @@ -36,4 +36,3 @@ func TestBuildShellProvisionerWithBuildVariablesSharing(t *testing.T) { helper.CleanUpAmi(t) } } - From 3f49b7c66e8a3838c5db63617ec9c080dc0681c2 Mon Sep 17 00:00:00 2001 From: Moss Date: Fri, 13 Mar 2020 17:17:42 +0100 Subject: [PATCH 35/41] Fix linter --- helper/tests/aws.go | 3 ++- helper/tests/core.go | 5 +++-- provisioner/shell/provisioner_acc_test.go | 7 ++++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/helper/tests/aws.go b/helper/tests/aws.go index e579bcde1..32f7e4754 100644 --- a/helper/tests/aws.go +++ b/helper/tests/aws.go @@ -1,10 +1,11 @@ package testshelper import ( + "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" awscommon "github.com/hashicorp/packer/builder/amazon/common" - "testing" ) type AWSHelper struct { diff --git a/helper/tests/core.go b/helper/tests/core.go index 05af712de..91ccef4de 100644 --- a/helper/tests/core.go +++ b/helper/tests/core.go @@ -2,13 +2,14 @@ package testshelper import ( "bytes" + "os" + "testing" + amazonebsbuilder "github.com/hashicorp/packer/builder/amazon/ebs" "github.com/hashicorp/packer/command" "github.com/hashicorp/packer/packer" fileprovisioner "github.com/hashicorp/packer/provisioner/file" "github.com/hashicorp/packer/provisioner/shell" - "os" - "testing" ) // fileExists returns true if the filename is found diff --git a/provisioner/shell/provisioner_acc_test.go b/provisioner/shell/provisioner_acc_test.go index 02508976d..ee25a7a67 100644 --- a/provisioner/shell/provisioner_acc_test.go +++ b/provisioner/shell/provisioner_acc_test.go @@ -1,12 +1,13 @@ package shell_test import ( - "github.com/hashicorp/go-uuid" - "github.com/hashicorp/packer/command" - "github.com/hashicorp/packer/helper/tests" "os" "path/filepath" "testing" + + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/packer/command" + "github.com/hashicorp/packer/helper/tests" ) func TestBuildShellProvisionerWithBuildVariablesSharing(t *testing.T) { From 5a8c628880a881fa74b552ba16f70ca61f4a941e Mon Sep 17 00:00:00 2001 From: Moss Date: Fri, 13 Mar 2020 17:50:05 +0100 Subject: [PATCH 36/41] Add acc test validation to avoid running with unit tests --- helper/tests/core.go | 20 +++++++++++++++++++ provisioner/shell/provisioner_acc_test.go | 2 ++ .../test-fixtures/shell-provisioner.json | 1 + 3 files changed, 23 insertions(+) diff --git a/helper/tests/core.go b/helper/tests/core.go index 91ccef4de..f48d92a75 100644 --- a/helper/tests/core.go +++ b/helper/tests/core.go @@ -2,6 +2,7 @@ package testshelper import ( "bytes" + "fmt" "os" "testing" @@ -65,3 +66,22 @@ func FatalCommand(t *testing.T, m command.Meta) { out.String(), err.String()) } + +const TestEnvVar = "PACKER_ACC" + +func AccTestPreValidate(t *testing.T) { + // We only run acceptance tests if an env var is set because they're + // slow and generally require some outside configuration. + if os.Getenv(TestEnvVar) == "" { + t.Skip(fmt.Sprintf( + "Acceptance tests skipped unless env '%s' set", + TestEnvVar)) + return + } + + // We require verbose mode so that the user knows what is going on. + if !testing.Verbose() { + t.Fatal("Acceptance tests must be run with the -v flag on tests") + return + } +} diff --git a/provisioner/shell/provisioner_acc_test.go b/provisioner/shell/provisioner_acc_test.go index ee25a7a67..889eaa56f 100644 --- a/provisioner/shell/provisioner_acc_test.go +++ b/provisioner/shell/provisioner_acc_test.go @@ -11,6 +11,8 @@ import ( ) func TestBuildShellProvisionerWithBuildVariablesSharing(t *testing.T) { + testshelper.AccTestPreValidate(t) + UUID, _ := uuid.GenerateUUID() os.Setenv("PACKER_RUN_UUID", UUID) c := &command.BuildCommand{ diff --git a/provisioner/shell/test-fixtures/shell-provisioner.json b/provisioner/shell/test-fixtures/shell-provisioner.json index df3604670..63ef3b0bb 100644 --- a/provisioner/shell/test-fixtures/shell-provisioner.json +++ b/provisioner/shell/test-fixtures/shell-provisioner.json @@ -7,6 +7,7 @@ "region": "us-east-1", "ssh_username": "ubuntu", "source_ami": "ami-0568456c", + "force_deregister" : true, "tags": { "packer-test": "true" } From 112d4daa3d3f7a51a8199a8ce90056dc59eb77bb Mon Sep 17 00:00:00 2001 From: Moss Date: Fri, 13 Mar 2020 17:52:33 +0100 Subject: [PATCH 37/41] Fix linter --- provisioner/shell/provisioner_acc_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/shell/provisioner_acc_test.go b/provisioner/shell/provisioner_acc_test.go index 889eaa56f..e25c97ef8 100644 --- a/provisioner/shell/provisioner_acc_test.go +++ b/provisioner/shell/provisioner_acc_test.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/go-uuid" "github.com/hashicorp/packer/command" - "github.com/hashicorp/packer/helper/tests" + testshelper "github.com/hashicorp/packer/helper/tests" ) func TestBuildShellProvisionerWithBuildVariablesSharing(t *testing.T) { From bcb7b8751cf0f10a874dc1baac8d8c57771a3422 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Fri, 13 Mar 2020 11:01:43 -0700 Subject: [PATCH 38/41] fix googlecompute password interpolation --- helper/communicator/step_connect_winrm.go | 1 + 1 file changed, 1 insertion(+) diff --git a/helper/communicator/step_connect_winrm.go b/helper/communicator/step_connect_winrm.go index 8825f98b0..5e7d13824 100644 --- a/helper/communicator/step_connect_winrm.go +++ b/helper/communicator/step_connect_winrm.go @@ -131,6 +131,7 @@ func (s *StepConnectWinRM) waitForWinRM(state multistep.StateBag, ctx context.Co } if config.Password != "" { password = config.Password + s.Config.WinRMPassword = password } } From aa95e4b93c095d3fda356a777097c9ae30269396 Mon Sep 17 00:00:00 2001 From: Robert Hencke Date: Fri, 13 Mar 2020 14:20:08 -0400 Subject: [PATCH 39/41] Fix small typo in amazon-ebssurrogate.html.md.erb --- website/source/docs/builders/amazon-ebssurrogate.html.md.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md.erb b/website/source/docs/builders/amazon-ebssurrogate.html.md.erb index bb2ff3595..aafa847bf 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md.erb +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md.erb @@ -172,7 +172,7 @@ variables are available: -> **Note:** Packer uses pre-built AMIs as the source for building images. These source AMIs may include volumes that are not flagged to be destroyed on termination of the instance building the new image. In addition to those -volumes created by this builder, any volumes inn the source AMI which are not +volumes created by this builder, any volumes in the source AMI which are not marked for deletion on termination will remain in your account. From 690bf714c55a0fd6165f3148c234510e4593ac32 Mon Sep 17 00:00:00 2001 From: Sylvia Moss Date: Mon, 16 Mar 2020 15:59:55 +0100 Subject: [PATCH 40/41] Add Codecov badge and remove report style (#8896) --- .codecov.yml | 2 +- README.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.codecov.yml b/.codecov.yml index dc306f95c..f2afee3a7 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,5 +1,5 @@ comment: - layout: "diff, flags, files" + layout: "flags, files" behavior: default require_changes: true # only comment on changes in coverage require_base: yes # [yes :: must have a base report to post] diff --git a/README.md b/README.md index 6b554993c..cd870c790 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![Windows Build Status][appveyor-badge]][appveyor] [![GoDoc][godoc-badge]][godoc] [![GoReportCard][report-badge]][report] +[![codecov](https://codecov.io/gh/hashicorp/packer/branch/master/graph/badge.svg)](https://codecov.io/gh/hashicorp/packer) [travis-badge]: https://travis-ci.org/hashicorp/packer.svg?branch=master [travis]: https://travis-ci.org/hashicorp/packer From 0d454f19bd66407b55e1c8c16d6b654643a9917d Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 16 Mar 2020 15:12:48 -0700 Subject: [PATCH 41/41] update changelog --- CHANGELOG.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7e82f6d2..e107f6383 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,23 +1,28 @@ ## 1.5.5 (Upcoming) ### IMPROVEMENTS: -* builder-vsphere-iso: Add the remote iso first so that it is first in boot - order, and clarify boot behavior. [GH-8732] * builder/azure: Add support for configurable KeyVault SKU [GH-8879] * builder/hyperv: Add `first_boot_device` setting to allow the selection of the initial device or device class used for booting the VM. [GH-8714] * builder/hyperv: Fix Hyper-V compacted disk size comparison [GH-8811] * builder/tencentcloud: Show tencentcloud image id after copy to desination region. [GH-8763] +* builder/vmware-iso: Do not perform dial test of NIC when ssh bastion is + required [GH-8877] * builder/vsphere-iso: Add ability to define multiple disks. [GH-8787] * builder/vsphere-iso: Add support for eagerly zeroed / scrubbed disks. [GH-8756] +* builder/vsphere-iso: Add the remote iso first so that it is first in boot + order, and clarify boot behavior. [GH-8732] +* communicator/ssh: Add flag to enable support for keyboard-interactive auth to + connect bastion [GH-8847] * core/hcl2: Add support in HCL2 configs for dynamic blocks, document for loops and splat expressions [GH-8720] * core/hcl2: Fix HCL2 local variables decoding to allow local usage within another local in the same locals block [GH-8755] * core/hcl2: Import new replace and regex_replace funcs from go-cty + documentation [GH-8863] +* core: Enable hcl files as var files in HCL mode [GH-8882] * core: Make "build" engine template variables SSHPublicKey and SSHPrivateKey strings [GH-8829] @@ -26,6 +31,7 @@ file limit. [GH-8800] * builder/azure: Fix HCL2 bug that prevented Azure and other builders from loading properly. [GH-8785] +* builder/googlecompute: Fix WinRMPassword template engine. [GH-8890] * builder/proxmox: Add new validation to catch that template_name cannot contain spaces. [GH-8799] * builder/vagrant: Fix path validation in ssh config step. [GH-8826] @@ -36,6 +42,12 @@ * core/hcl2: Fix logic for parsing literal value variables [GH-8834] * core: Fix "build" template engine interpolation for certain fields in certain provisioners. [GH-8771] +* core: Fix bug where user var recursion could fail intermittently when used + with env vars [GH-8875] +* plugins: Make plugin discovery stricter with respect to periods so that users + can disable plugins by renaming the extension [GH-8735] +* provisioner/shell: "inline" config option is now a template engine. [GH-8883] + ## 1.5.4 (February 14, 2020) no-change release to fix code-signing on OSX binaries. Since checksums for these