2021-09-22 23:53:33 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"io/ioutil"
|
2021-10-11 23:44:44 +02:00
|
|
|
"os"
|
2021-09-22 23:53:33 +02:00
|
|
|
"testing"
|
|
|
|
|
2021-10-11 23:44:44 +02:00
|
|
|
expect "github.com/Netflix/go-expect"
|
2021-09-22 23:53:33 +02:00
|
|
|
tfe "github.com/hashicorp/go-tfe"
|
|
|
|
"github.com/hashicorp/terraform/internal/e2e"
|
2021-10-28 01:07:12 +02:00
|
|
|
tfversion "github.com/hashicorp/terraform/version"
|
2021-09-22 23:53:33 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func Test_terraform_apply_autoApprove(t *testing.T) {
|
2021-11-12 18:00:24 +01:00
|
|
|
skipIfMissingEnvVar(t)
|
2021-10-28 01:07:12 +02:00
|
|
|
skipWithoutRemoteTerraformVersion(t)
|
|
|
|
|
2021-09-22 23:53:33 +02:00
|
|
|
ctx := context.Background()
|
2021-10-11 23:44:44 +02:00
|
|
|
|
2021-09-22 23:53:33 +02:00
|
|
|
cases := map[string]struct {
|
2021-10-11 23:44:44 +02:00
|
|
|
operations []operationSets
|
|
|
|
validations func(t *testing.T, orgName string)
|
2021-09-22 23:53:33 +02:00
|
|
|
}{
|
2021-10-11 23:44:44 +02:00
|
|
|
"workspace manual apply, terraform apply without auto-approve, expect prompt": {
|
|
|
|
operations: []operationSets{
|
2021-09-22 23:53:33 +02:00
|
|
|
{
|
2021-10-11 23:44:44 +02:00
|
|
|
prep: func(t *testing.T, orgName, dir string) {
|
|
|
|
wsName := "app"
|
|
|
|
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
|
|
|
|
Name: tfe.String(wsName),
|
2021-10-28 01:07:12 +02:00
|
|
|
TerraformVersion: tfe.String(tfversion.String()),
|
2021-10-11 23:44:44 +02:00
|
|
|
AutoApply: tfe.Bool(false),
|
|
|
|
})
|
|
|
|
tfBlock := terraformConfigCloudBackendName(orgName, wsName)
|
|
|
|
writeMainTF(t, tfBlock, dir)
|
|
|
|
},
|
|
|
|
commands: []tfCommand{
|
|
|
|
{
|
|
|
|
command: []string{"init"},
|
2021-10-19 23:06:41 +02:00
|
|
|
expectedCmdOutput: `Terraform Cloud has been successfully initialized!`,
|
2021-10-11 23:44:44 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
command: []string{"apply"},
|
|
|
|
expectedCmdOutput: `Do you want to perform these actions in workspace "app"?`,
|
|
|
|
userInput: []string{"yes"},
|
|
|
|
postInputOutput: []string{`Apply complete!`},
|
|
|
|
},
|
|
|
|
},
|
2021-09-22 23:53:33 +02:00
|
|
|
},
|
|
|
|
},
|
2021-10-11 23:44:44 +02:00
|
|
|
validations: func(t *testing.T, orgName string) {
|
|
|
|
workspace, err := tfeClient.Workspaces.ReadWithOptions(ctx, orgName, "app", &tfe.WorkspaceReadOptions{Include: "current_run"})
|
2021-09-22 23:53:33 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if workspace.CurrentRun == nil {
|
|
|
|
t.Fatal("Expected workspace to have run, but got nil")
|
|
|
|
}
|
2021-10-11 23:44:44 +02:00
|
|
|
if workspace.CurrentRun.Status != tfe.RunApplied {
|
|
|
|
t.Fatalf("Expected run status to be `applied`, but is %s", workspace.CurrentRun.Status)
|
2021-09-22 23:53:33 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
2021-10-11 23:44:44 +02:00
|
|
|
"workspace auto apply, terraform apply without auto-approve, expect prompt": {
|
|
|
|
operations: []operationSets{
|
2021-09-22 23:53:33 +02:00
|
|
|
{
|
2021-10-11 23:44:44 +02:00
|
|
|
prep: func(t *testing.T, orgName, dir string) {
|
|
|
|
wsName := "app"
|
|
|
|
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
|
|
|
|
Name: tfe.String(wsName),
|
2021-10-28 01:07:12 +02:00
|
|
|
TerraformVersion: tfe.String(tfversion.String()),
|
2021-10-11 23:44:44 +02:00
|
|
|
AutoApply: tfe.Bool(true),
|
|
|
|
})
|
|
|
|
tfBlock := terraformConfigCloudBackendName(orgName, wsName)
|
|
|
|
writeMainTF(t, tfBlock, dir)
|
|
|
|
},
|
|
|
|
commands: []tfCommand{
|
|
|
|
{
|
|
|
|
command: []string{"init"},
|
2021-10-19 23:06:41 +02:00
|
|
|
expectedCmdOutput: `Terraform Cloud has been successfully initialized!`,
|
2021-10-11 23:44:44 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
command: []string{"apply"},
|
|
|
|
expectedCmdOutput: `Do you want to perform these actions in workspace "app"?`,
|
|
|
|
userInput: []string{"yes"},
|
|
|
|
postInputOutput: []string{`Apply complete!`},
|
|
|
|
},
|
|
|
|
},
|
2021-09-22 23:53:33 +02:00
|
|
|
},
|
|
|
|
},
|
2021-10-11 23:44:44 +02:00
|
|
|
validations: func(t *testing.T, orgName string) {
|
|
|
|
workspace, err := tfeClient.Workspaces.ReadWithOptions(ctx, orgName, "app", &tfe.WorkspaceReadOptions{Include: "current_run"})
|
2021-09-22 23:53:33 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if workspace.CurrentRun == nil {
|
2021-10-11 23:44:44 +02:00
|
|
|
t.Fatal("Expected workspace to have run, but got nil")
|
2021-09-22 23:53:33 +02:00
|
|
|
}
|
2021-10-11 23:44:44 +02:00
|
|
|
if workspace.CurrentRun.Status != tfe.RunApplied {
|
|
|
|
t.Fatalf("Expected run status to be `applied`, but is %s", workspace.CurrentRun.Status)
|
2021-09-22 23:53:33 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
2021-10-11 23:44:44 +02:00
|
|
|
"workspace manual apply, terraform apply with auto-approve, no prompt": {
|
|
|
|
operations: []operationSets{
|
2021-09-22 23:53:33 +02:00
|
|
|
{
|
2021-10-11 23:44:44 +02:00
|
|
|
prep: func(t *testing.T, orgName, dir string) {
|
|
|
|
wsName := "app"
|
|
|
|
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
|
|
|
|
Name: tfe.String(wsName),
|
2021-10-28 01:07:12 +02:00
|
|
|
TerraformVersion: tfe.String(tfversion.String()),
|
2021-10-11 23:44:44 +02:00
|
|
|
AutoApply: tfe.Bool(false),
|
|
|
|
})
|
|
|
|
tfBlock := terraformConfigCloudBackendName(orgName, wsName)
|
|
|
|
writeMainTF(t, tfBlock, dir)
|
|
|
|
},
|
|
|
|
commands: []tfCommand{
|
|
|
|
{
|
|
|
|
command: []string{"init"},
|
2021-10-19 23:06:41 +02:00
|
|
|
expectedCmdOutput: `Terraform Cloud has been successfully initialized!`,
|
2021-10-11 23:44:44 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
command: []string{"apply", "-auto-approve"},
|
|
|
|
expectedCmdOutput: `Apply complete!`,
|
|
|
|
},
|
|
|
|
},
|
2021-09-22 23:53:33 +02:00
|
|
|
},
|
|
|
|
},
|
2021-10-11 23:44:44 +02:00
|
|
|
validations: func(t *testing.T, orgName string) {
|
|
|
|
workspace, err := tfeClient.Workspaces.ReadWithOptions(ctx, orgName, "app", &tfe.WorkspaceReadOptions{Include: "current_run"})
|
2021-09-22 23:53:33 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if workspace.CurrentRun == nil {
|
2021-10-11 23:44:44 +02:00
|
|
|
t.Fatal("Expected workspace to have run, but got nil")
|
2021-09-22 23:53:33 +02:00
|
|
|
}
|
|
|
|
if workspace.CurrentRun.Status != tfe.RunApplied {
|
|
|
|
t.Fatalf("Expected run status to be `applied`, but is %s", workspace.CurrentRun.Status)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
2021-10-11 23:44:44 +02:00
|
|
|
"workspace auto apply, terraform apply with auto-approve, no prompt": {
|
|
|
|
operations: []operationSets{
|
2021-09-22 23:53:33 +02:00
|
|
|
{
|
2021-10-11 23:44:44 +02:00
|
|
|
prep: func(t *testing.T, orgName, dir string) {
|
|
|
|
wsName := "app"
|
|
|
|
_ = createWorkspace(t, orgName, tfe.WorkspaceCreateOptions{
|
|
|
|
Name: tfe.String(wsName),
|
2021-10-28 01:07:12 +02:00
|
|
|
TerraformVersion: tfe.String(tfversion.String()),
|
2021-10-11 23:44:44 +02:00
|
|
|
AutoApply: tfe.Bool(true),
|
|
|
|
})
|
|
|
|
tfBlock := terraformConfigCloudBackendName(orgName, wsName)
|
|
|
|
writeMainTF(t, tfBlock, dir)
|
|
|
|
},
|
|
|
|
commands: []tfCommand{
|
|
|
|
{
|
|
|
|
command: []string{"init"},
|
2021-10-19 23:06:41 +02:00
|
|
|
expectedCmdOutput: `Terraform Cloud has been successfully initialized!`,
|
2021-10-11 23:44:44 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
command: []string{"apply", "-auto-approve"},
|
|
|
|
expectedCmdOutput: `Apply complete!`,
|
|
|
|
},
|
|
|
|
},
|
2021-09-22 23:53:33 +02:00
|
|
|
},
|
|
|
|
},
|
2021-10-11 23:44:44 +02:00
|
|
|
validations: func(t *testing.T, orgName string) {
|
|
|
|
workspace, err := tfeClient.Workspaces.ReadWithOptions(ctx, orgName, "app", &tfe.WorkspaceReadOptions{Include: "current_run"})
|
2021-09-22 23:53:33 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if workspace.CurrentRun == nil {
|
2021-10-11 23:44:44 +02:00
|
|
|
t.Fatal("Expected workspace to have run, but got nil")
|
2021-09-22 23:53:33 +02:00
|
|
|
}
|
|
|
|
if workspace.CurrentRun.Status != tfe.RunApplied {
|
|
|
|
t.Fatalf("Expected run status to be `applied`, but is %s", workspace.CurrentRun.Status)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2021-11-17 23:00:47 +01:00
|
|
|
for name, tc := range cases {
|
|
|
|
tc := tc
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
// t.Parallel()
|
|
|
|
organization, cleanup := createOrganization(t)
|
|
|
|
defer cleanup()
|
|
|
|
exp, err := expect.NewConsole(defaultOpts()...)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer exp.Close()
|
2021-10-11 23:44:44 +02:00
|
|
|
|
2021-11-17 23:00:47 +01:00
|
|
|
tmpDir, err := ioutil.TempDir("", "terraform-test")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(tmpDir)
|
2021-09-22 23:53:33 +02:00
|
|
|
|
2021-11-17 23:00:47 +01:00
|
|
|
tf := e2e.NewBinary(terraformBin, tmpDir)
|
|
|
|
tf.AddEnv(cliConfigFileEnv)
|
|
|
|
defer tf.Close()
|
2021-10-11 23:44:44 +02:00
|
|
|
|
2021-11-17 23:00:47 +01:00
|
|
|
for _, op := range tc.operations {
|
|
|
|
op.prep(t, organization.Name, tf.WorkDir())
|
|
|
|
for _, tfCmd := range op.commands {
|
|
|
|
cmd := tf.Cmd(tfCmd.command...)
|
|
|
|
cmd.Stdin = exp.Tty()
|
|
|
|
cmd.Stdout = exp.Tty()
|
|
|
|
cmd.Stderr = exp.Tty()
|
2021-11-12 18:00:24 +01:00
|
|
|
|
2021-11-17 23:00:47 +01:00
|
|
|
err = cmd.Start()
|
2021-10-11 23:44:44 +02:00
|
|
|
if err != nil {
|
2021-11-17 23:00:47 +01:00
|
|
|
t.Fatal(err)
|
2021-10-11 23:44:44 +02:00
|
|
|
}
|
2021-09-22 23:53:33 +02:00
|
|
|
|
2021-11-17 23:00:47 +01:00
|
|
|
if tfCmd.expectedCmdOutput != "" {
|
|
|
|
got, err := exp.ExpectString(tfCmd.expectedCmdOutput)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error while waiting for output\nwant: %s\nerror: %s\noutput\n%s", tfCmd.expectedCmdOutput, err, got)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lenInput := len(tfCmd.userInput)
|
|
|
|
lenInputOutput := len(tfCmd.postInputOutput)
|
|
|
|
if lenInput > 0 {
|
|
|
|
for i := 0; i < lenInput; i++ {
|
|
|
|
input := tfCmd.userInput[i]
|
|
|
|
exp.SendLine(input)
|
|
|
|
// use the index to find the corresponding
|
|
|
|
// output that matches the input.
|
|
|
|
if lenInputOutput-1 >= i {
|
|
|
|
output := tfCmd.postInputOutput[i]
|
|
|
|
_, err := exp.ExpectString(output)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2021-10-11 23:44:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-17 23:00:47 +01:00
|
|
|
err = cmd.Wait()
|
|
|
|
if err != nil && !tfCmd.expectError {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2021-10-11 23:44:44 +02:00
|
|
|
}
|
2021-09-22 23:53:33 +02:00
|
|
|
}
|
|
|
|
|
2021-11-17 23:00:47 +01:00
|
|
|
if tc.validations != nil {
|
|
|
|
tc.validations(t, organization.Name)
|
|
|
|
}
|
|
|
|
})
|
2021-09-22 23:53:33 +02:00
|
|
|
}
|
|
|
|
}
|