Merge pull request #25960 from hashicorp/alisdair/backend-config-override-fix
command: Fix backend config override validation
This commit is contained in:
commit
c5d9935c0e
|
@ -861,16 +861,31 @@ func (c *InitCommand) backendConfigOverrideBody(flags rawFlags, schema *configsc
|
||||||
// The value is interpreted as a filename.
|
// The value is interpreted as a filename.
|
||||||
newBody, fileDiags := c.loadHCLFile(item.Value)
|
newBody, fileDiags := c.loadHCLFile(item.Value)
|
||||||
diags = diags.Append(fileDiags)
|
diags = diags.Append(fileDiags)
|
||||||
// Verify that the file contains only key-values pairs, and not a
|
if fileDiags.HasErrors() {
|
||||||
// full backend config block. JustAttributes() will return an error
|
continue
|
||||||
// if blocks are found
|
}
|
||||||
_, attrDiags := newBody.JustAttributes()
|
// Generate an HCL body schema for the backend block.
|
||||||
if attrDiags.HasErrors() {
|
var bodySchema hcl.BodySchema
|
||||||
diags = diags.Append(tfdiags.Sourceless(
|
for name, attr := range schema.Attributes {
|
||||||
tfdiags.Error,
|
bodySchema.Attributes = append(bodySchema.Attributes, hcl.AttributeSchema{
|
||||||
"Invalid backend configuration file",
|
Name: name,
|
||||||
fmt.Sprintf("The backend configuration file %q given on the command line must contain key-value pairs only, and not configuration blocks.", item.Value),
|
Required: attr.Required,
|
||||||
))
|
})
|
||||||
|
}
|
||||||
|
for name, block := range schema.BlockTypes {
|
||||||
|
var labelNames []string
|
||||||
|
if block.Nesting == configschema.NestingMap {
|
||||||
|
labelNames = append(labelNames, "key")
|
||||||
|
}
|
||||||
|
bodySchema.Blocks = append(bodySchema.Blocks, hcl.BlockHeaderSchema{
|
||||||
|
Type: name,
|
||||||
|
LabelNames: labelNames,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// Verify that the file body matches the expected backend schema.
|
||||||
|
_, schemaDiags := newBody.Content(&bodySchema)
|
||||||
|
diags = diags.Append(schemaDiags)
|
||||||
|
if schemaDiags.HasErrors() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
flushVals() // deal with any accumulated individual values first
|
flushVals() // deal with any accumulated individual values first
|
||||||
|
|
|
@ -355,8 +355,8 @@ func TestInit_backendConfigFile(t *testing.T) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// the backend config file must be a set of key-value pairs and not a full backend {} block
|
// the backend config file must not be a full terraform block
|
||||||
t.Run("invalid-config-file", func(t *testing.T) {
|
t.Run("full-backend-config-file", func(t *testing.T) {
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
c := &InitCommand{
|
c := &InitCommand{
|
||||||
Meta: Meta{
|
Meta: Meta{
|
||||||
|
@ -368,10 +368,67 @@ func TestInit_backendConfigFile(t *testing.T) {
|
||||||
if code := c.Run(args); code != 1 {
|
if code := c.Run(args); code != 1 {
|
||||||
t.Fatalf("expected error, got success\n")
|
t.Fatalf("expected error, got success\n")
|
||||||
}
|
}
|
||||||
if !strings.Contains(ui.ErrorWriter.String(), "Invalid backend configuration file") {
|
if !strings.Contains(ui.ErrorWriter.String(), "Unsupported block type") {
|
||||||
t.Fatalf("wrong error: %s", ui.ErrorWriter)
|
t.Fatalf("wrong error: %s", ui.ErrorWriter)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// the backend config file must match the schema for the backend
|
||||||
|
t.Run("invalid-config-file", func(t *testing.T) {
|
||||||
|
ui := new(cli.MockUi)
|
||||||
|
c := &InitCommand{
|
||||||
|
Meta: Meta{
|
||||||
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
|
Ui: ui,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
args := []string{"-backend-config", "invalid.config"}
|
||||||
|
if code := c.Run(args); code != 1 {
|
||||||
|
t.Fatalf("expected error, got success\n")
|
||||||
|
}
|
||||||
|
if !strings.Contains(ui.ErrorWriter.String(), "Unsupported argument") {
|
||||||
|
t.Fatalf("wrong error: %s", ui.ErrorWriter)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// missing file is an error
|
||||||
|
t.Run("missing-config-file", func(t *testing.T) {
|
||||||
|
ui := new(cli.MockUi)
|
||||||
|
c := &InitCommand{
|
||||||
|
Meta: Meta{
|
||||||
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
|
Ui: ui,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
args := []string{"-backend-config", "missing.config"}
|
||||||
|
if code := c.Run(args); code != 1 {
|
||||||
|
t.Fatalf("expected error, got success\n")
|
||||||
|
}
|
||||||
|
if !strings.Contains(ui.ErrorWriter.String(), "Failed to read file") {
|
||||||
|
t.Fatalf("wrong error: %s", ui.ErrorWriter)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// blank filename clears the backend config
|
||||||
|
t.Run("blank-config-file", func(t *testing.T) {
|
||||||
|
ui := new(cli.MockUi)
|
||||||
|
c := &InitCommand{
|
||||||
|
Meta: Meta{
|
||||||
|
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||||
|
Ui: ui,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
args := []string{"-backend-config="}
|
||||||
|
if code := c.Run(args); code != 0 {
|
||||||
|
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read our saved backend config and verify the backend config is empty
|
||||||
|
state := testDataStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename))
|
||||||
|
if got, want := normalizeJSON(t, state.Backend.ConfigRaw), `{"path":null,"workspace_dir":null}`; got != want {
|
||||||
|
t.Errorf("wrong config\ngot: %s\nwant: %s", got, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInit_backendConfigFilePowershellConfusion(t *testing.T) {
|
func TestInit_backendConfigFilePowershellConfusion(t *testing.T) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// the -backend-config flag on init cannot be used to point to a "full" backend
|
// the -backend-config flag on init cannot be used to point to a "full" backend
|
||||||
// block, only key-value pairs (like terraform.tfvars)
|
// block
|
||||||
terraform {
|
terraform {
|
||||||
backend "local" {
|
backend "local" {
|
||||||
path = "hello"
|
path = "hello"
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
path = "hello"
|
||||||
|
foo = "bar"
|
Loading…
Reference in New Issue