Fix non-string elements in tags schema

pull/35907/head
Brandon Croft 2 years ago
parent 18ca2d5a79
commit 9d0133a541
No known key found for this signature in database
GPG Key ID: B01E32423322EB9D

@ -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…
Cancel
Save