command: Taint should respect required_version
Despite not requiring the configuration for any other reason, the taint subcommand should not execute if the required_version constraints cannot be met. Doing so can result in an undesirable state file upgrade.
This commit is contained in:
parent
ce2e59f835
commit
14a233b019
|
@ -3,11 +3,13 @@ package command
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/addrs"
|
||||
"github.com/hashicorp/terraform/command/clistate"
|
||||
"github.com/hashicorp/terraform/states"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"github.com/hashicorp/terraform/tfdiags"
|
||||
)
|
||||
|
||||
|
@ -62,6 +64,34 @@ func (c *TaintCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
// Load the config and check the core version requirements are satisfied
|
||||
loader, err := c.initConfigLoader()
|
||||
if err != nil {
|
||||
diags = diags.Append(err)
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error getting pwd: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
config, configDiags := loader.LoadConfig(pwd)
|
||||
diags = diags.Append(configDiags)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
versionDiags := terraform.CheckCoreVersionRequirements(config)
|
||||
diags = diags.Append(versionDiags)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
// Load the backend
|
||||
b, backendDiags := c.Backend(nil)
|
||||
diags = diags.Append(backendDiags)
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/mitchellh/cli"
|
||||
|
||||
"github.com/hashicorp/terraform/addrs"
|
||||
"github.com/hashicorp/terraform/helper/copy"
|
||||
"github.com/hashicorp/terraform/states"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
@ -407,6 +408,57 @@ func TestTaint_module(t *testing.T) {
|
|||
testStateOutput(t, statePath, testTaintModuleStr)
|
||||
}
|
||||
|
||||
func TestTaint_checkRequiredVersion(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := tempDir(t)
|
||||
copy.CopyDir(testFixturePath("taint-check-required-version"), td)
|
||||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
// Write the temp state
|
||||
state := &terraform.State{
|
||||
Modules: []*terraform.ModuleState{
|
||||
{
|
||||
Path: []string{"root"},
|
||||
Resources: map[string]*terraform.ResourceState{
|
||||
"test_instance.foo": {
|
||||
Type: "test_instance",
|
||||
Primary: &terraform.InstanceState{
|
||||
ID: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
path := testStateFileDefault(t, state)
|
||||
|
||||
ui := cli.NewMockUi()
|
||||
c := &TaintCommand{
|
||||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{"test_instance.foo"}
|
||||
if code := c.Run(args); code != 1 {
|
||||
t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, ui.ErrorWriter.String(), ui.OutputWriter.String())
|
||||
}
|
||||
|
||||
// State is unchanged
|
||||
testStateOutput(t, path, testTaintDefaultStr)
|
||||
|
||||
// Required version diags are correct
|
||||
errStr := ui.ErrorWriter.String()
|
||||
if !strings.Contains(errStr, `required_version = "~> 0.9.0"`) {
|
||||
t.Fatalf("output should point to unmet version constraint, but is:\n\n%s", errStr)
|
||||
}
|
||||
if strings.Contains(errStr, `required_version = ">= 0.13.0"`) {
|
||||
t.Fatalf("output should not point to met version constraint, but is:\n\n%s", errStr)
|
||||
}
|
||||
}
|
||||
|
||||
const testTaintStr = `
|
||||
test_instance.foo: (tainted)
|
||||
ID = bar
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
terraform {
|
||||
required_version = "~> 0.9.0"
|
||||
}
|
||||
|
||||
terraform {
|
||||
required_version = ">= 0.13.0"
|
||||
}
|
Loading…
Reference in New Issue