mirror of
https://github.com/hashicorp/terraform.git
synced 2026-05-28 04:03:27 -04:00
Fix non-string elements in tags schema
This commit is contained in:
parent
18ca2d5a79
commit
9d0133a541
3 changed files with 50 additions and 8 deletions
|
|
@ -22,7 +22,6 @@ import (
|
|||
"github.com/hashicorp/terraform-svchost/disco"
|
||||
"github.com/mitchellh/colorstring"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/gocty"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/backend"
|
||||
"github.com/hashicorp/terraform/internal/backend/backendrun"
|
||||
|
|
@ -499,21 +498,36 @@ func resolveCloudConfig(obj cty.Value) (cloudConfig, tfdiags.Diagnostics) {
|
|||
tagsAsMap := make(map[string]string)
|
||||
if val.Type().IsObjectType() || val.Type().IsMapType() {
|
||||
for k, v := range val.AsValueMap() {
|
||||
if v.Type() != cty.String {
|
||||
diags = diags.Append(errors.New("tag object values must be strings"))
|
||||
return ret, diags
|
||||
}
|
||||
tagsAsMap[k] = v.AsString()
|
||||
}
|
||||
log.Printf("[TRACE] cloud: using tags %q from cloud config block", tagsAsMap)
|
||||
ret.workspaceMapping.TagsAsMap = tagsAsMap
|
||||
} else if val.Type().IsSetType() {
|
||||
} else if val.Type().IsTupleType() || val.Type().IsSetType() {
|
||||
var tagsAsSet []string
|
||||
err := gocty.FromCtyValue(val, &tagsAsSet)
|
||||
if err != nil {
|
||||
diags = diags.Append(fmt.Errorf("an unexpected error occurred: %w", err))
|
||||
} else {
|
||||
log.Printf("[TRACE] cloud: using tags %q from cloud config block", tagsAsSet)
|
||||
length := val.LengthInt()
|
||||
if length > 0 {
|
||||
it := val.ElementIterator()
|
||||
for it.Next() {
|
||||
_, v := it.Element()
|
||||
if !v.Type().Equals(cty.String) {
|
||||
diags = diags.Append(errors.New("tag elements must be strings"))
|
||||
return ret, diags
|
||||
}
|
||||
if vs := v.AsString(); vs != "" {
|
||||
tagsAsSet = append(tagsAsSet, vs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("[TRACE] cloud: using tags %q from cloud config block", tagsAsSet)
|
||||
ret.workspaceMapping.TagsAsSet = tagsAsSet
|
||||
} else {
|
||||
diags = diags.Append(fmt.Errorf("tags must be a set or object, not %s", val.Type().FriendlyName()))
|
||||
return ret, diags
|
||||
}
|
||||
}
|
||||
if val := workspaces.GetAttr("project"); !val.IsNull() {
|
||||
|
|
|
|||
|
|
@ -687,6 +687,34 @@ func TestCloud_config(t *testing.T) {
|
|||
})),
|
||||
confErr: `tags must be a set or object, not string`,
|
||||
},
|
||||
"invalid tags dynamic type, object with non-string": {
|
||||
config: cty.ObjectVal((map[string]cty.Value{
|
||||
"hostname": cty.NullVal(cty.String),
|
||||
"organization": cty.StringVal("hashicorp"),
|
||||
"token": cty.NullVal(cty.String),
|
||||
"workspaces": cty.ObjectVal(map[string]cty.Value{
|
||||
"name": cty.NullVal(cty.String),
|
||||
"tags": cty.MapVal(map[string]cty.Value{
|
||||
"dept": cty.NumberIntVal(1),
|
||||
}),
|
||||
"project": cty.NullVal(cty.String),
|
||||
}),
|
||||
})),
|
||||
confErr: `tag object values must be strings`,
|
||||
},
|
||||
"invalid tags dynamic type, tuple non-string": {
|
||||
config: cty.ObjectVal((map[string]cty.Value{
|
||||
"hostname": cty.NullVal(cty.String),
|
||||
"organization": cty.StringVal("hashicorp"),
|
||||
"token": cty.NullVal(cty.String),
|
||||
"workspaces": cty.ObjectVal(map[string]cty.Value{
|
||||
"name": cty.NullVal(cty.String),
|
||||
"tags": cty.TupleVal([]cty.Value{cty.NumberIntVal(1)}),
|
||||
"project": cty.NullVal(cty.String),
|
||||
}),
|
||||
})),
|
||||
confErr: `tag elements must be strings`,
|
||||
},
|
||||
"null config": {
|
||||
config: cty.NullVal(cty.EmptyObject),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -763,7 +763,7 @@ func (m *Meta) determineInitReason(previousBackendType string, currentBackendTyp
|
|||
// from the backend state. This should be used only when a user runs
|
||||
// `terraform init -backend=false`. This function returns a local backend if
|
||||
// there is no backend state or no backend configured.
|
||||
func (m *Meta) backendFromState(ctx context.Context) (backend.Backend, tfdiags.Diagnostics) {
|
||||
func (m *Meta) backendFromState(_ context.Context) (backend.Backend, tfdiags.Diagnostics) {
|
||||
var diags tfdiags.Diagnostics
|
||||
// Get the path to where we store a local cache of backend configuration
|
||||
// if we're using a remote backend. This may not yet exist which means
|
||||
|
|
|
|||
Loading…
Reference in a new issue