mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
helper/schema: Remove missed subfields when parent list is removed (#11498)
This commit is contained in:
parent
01a6bd7592
commit
d5ac48de2a
@ -634,6 +634,19 @@ func (m schemaMap) InternalValidate(topSchemaMap schemaMap) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m schemaMap) markAsRemoved(k string, schema *Schema, diff *terraform.InstanceDiff) {
|
||||||
|
existingDiff, ok := diff.Attributes[k]
|
||||||
|
if ok {
|
||||||
|
existingDiff.NewRemoved = true
|
||||||
|
diff.Attributes[k] = schema.finalizeDiff(existingDiff)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
diff.Attributes[k] = schema.finalizeDiff(&terraform.ResourceAttrDiff{
|
||||||
|
NewRemoved: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (m schemaMap) diff(
|
func (m schemaMap) diff(
|
||||||
k string,
|
k string,
|
||||||
schema *Schema,
|
schema *Schema,
|
||||||
@ -757,6 +770,7 @@ func (m schemaMap) diffList(
|
|||||||
|
|
||||||
switch t := schema.Elem.(type) {
|
switch t := schema.Elem.(type) {
|
||||||
case *Resource:
|
case *Resource:
|
||||||
|
countDiff, cOk := diff.GetAttribute(k + ".#")
|
||||||
// This is a complex resource
|
// This is a complex resource
|
||||||
for i := 0; i < maxLen; i++ {
|
for i := 0; i < maxLen; i++ {
|
||||||
for k2, schema := range t.Schema {
|
for k2, schema := range t.Schema {
|
||||||
@ -765,6 +779,15 @@ func (m schemaMap) diffList(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If parent list is being removed
|
||||||
|
// remove all subfields which were missed by the diff func
|
||||||
|
// We process these separately because type-specific diff functions
|
||||||
|
// lack the context (hierarchy of fields)
|
||||||
|
subKeyIsCount := strings.HasSuffix(subK, ".#")
|
||||||
|
if cOk && countDiff.New == "0" && !subKeyIsCount {
|
||||||
|
m.markAsRemoved(subK, schema, diff)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *Schema:
|
case *Schema:
|
||||||
|
@ -2651,6 +2651,274 @@ func TestSchemaMap_Diff(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Name: "Removal of TypeList should cause nested Bool fields w/ Default to be removed too",
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"deployment_group_name": &Schema{
|
||||||
|
Type: TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"alarm_configuration": &Schema{
|
||||||
|
Type: TypeList,
|
||||||
|
Optional: true,
|
||||||
|
MaxItems: 1,
|
||||||
|
Elem: &Resource{
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"alarms": &Schema{
|
||||||
|
Type: TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Set: HashString,
|
||||||
|
Elem: &Schema{Type: TypeString},
|
||||||
|
},
|
||||||
|
|
||||||
|
"enabled": &Schema{
|
||||||
|
Type: TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"ignore_poll_alarm_failure": &Schema{
|
||||||
|
Type: TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: &terraform.InstanceState{
|
||||||
|
Attributes: map[string]string{
|
||||||
|
"alarm_configuration.#": "1",
|
||||||
|
"alarm_configuration.0.alarms.#": "1",
|
||||||
|
"alarm_configuration.0.alarms.2356372769": "foo",
|
||||||
|
"alarm_configuration.0.enabled": "true",
|
||||||
|
"alarm_configuration.0.ignore_poll_alarm_failure": "false",
|
||||||
|
"deployment_group_name": "foo-group-32345345345",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"deployment_group_name": "foo-group-32345345345",
|
||||||
|
},
|
||||||
|
|
||||||
|
Diff: &terraform.InstanceDiff{
|
||||||
|
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||||
|
"alarm_configuration.#": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "1",
|
||||||
|
New: "0",
|
||||||
|
NewRemoved: false,
|
||||||
|
},
|
||||||
|
"alarm_configuration.0.alarms": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "",
|
||||||
|
New: "",
|
||||||
|
NewRemoved: true,
|
||||||
|
},
|
||||||
|
"alarm_configuration.0.alarms.#": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "1",
|
||||||
|
New: "0",
|
||||||
|
NewRemoved: false,
|
||||||
|
},
|
||||||
|
"alarm_configuration.0.alarms.2356372769": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "foo",
|
||||||
|
New: "",
|
||||||
|
NewRemoved: true,
|
||||||
|
},
|
||||||
|
"alarm_configuration.0.enabled": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "true",
|
||||||
|
New: "false",
|
||||||
|
NewRemoved: true,
|
||||||
|
},
|
||||||
|
"alarm_configuration.0.ignore_poll_alarm_failure": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "",
|
||||||
|
New: "",
|
||||||
|
NewRemoved: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Name: "Removal of TypeList should cause all empty nested String fields to be removed too",
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"bucket": {
|
||||||
|
Type: TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"acl": {
|
||||||
|
Type: TypeString,
|
||||||
|
Default: "private",
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"website": {
|
||||||
|
Type: TypeList,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &Resource{
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"index_document": {
|
||||||
|
Type: TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"error_document": {
|
||||||
|
Type: TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"redirect_all_requests_to": {
|
||||||
|
Type: TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"routing_rules": {
|
||||||
|
Type: TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: &terraform.InstanceState{
|
||||||
|
Attributes: map[string]string{
|
||||||
|
"acl": "public-read",
|
||||||
|
"bucket": "tf-test-bucket-5011072831090096749",
|
||||||
|
"website.#": "1",
|
||||||
|
"website.0.error_document": "error.html",
|
||||||
|
"website.0.index_document": "index.html",
|
||||||
|
"website.0.redirect_all_requests_to": "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"acl": "public-read",
|
||||||
|
"bucket": "tf-test-bucket-5011072831090096749",
|
||||||
|
},
|
||||||
|
|
||||||
|
Diff: &terraform.InstanceDiff{
|
||||||
|
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||||
|
"website.#": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "1",
|
||||||
|
New: "0",
|
||||||
|
NewRemoved: false,
|
||||||
|
},
|
||||||
|
"website.0.index_document": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "index.html",
|
||||||
|
New: "",
|
||||||
|
NewRemoved: true,
|
||||||
|
},
|
||||||
|
"website.0.error_document": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "error.html",
|
||||||
|
New: "",
|
||||||
|
NewRemoved: true,
|
||||||
|
},
|
||||||
|
"website.0.redirect_all_requests_to": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "",
|
||||||
|
New: "",
|
||||||
|
NewRemoved: true,
|
||||||
|
},
|
||||||
|
"website.0.routing_rules": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "",
|
||||||
|
New: "",
|
||||||
|
NewRemoved: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Name: "Removal of TypeList should cause nested Int fields w/ Default to be removed too",
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"availability_zones": &Schema{
|
||||||
|
Type: TypeSet,
|
||||||
|
Elem: &Schema{Type: TypeString},
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
Set: HashString,
|
||||||
|
},
|
||||||
|
|
||||||
|
"access_logs": &Schema{
|
||||||
|
Type: TypeList,
|
||||||
|
Optional: true,
|
||||||
|
MaxItems: 1,
|
||||||
|
Elem: &Resource{
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"interval": &Schema{
|
||||||
|
Type: TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Default: 60,
|
||||||
|
},
|
||||||
|
"bucket": &Schema{
|
||||||
|
Type: TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"bucket_prefix": &Schema{
|
||||||
|
Type: TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"enabled": &Schema{
|
||||||
|
Type: TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: &terraform.InstanceState{
|
||||||
|
Attributes: map[string]string{
|
||||||
|
"access_logs.#": "1",
|
||||||
|
"access_logs.0.bucket": "terraform-access-logs-bucket-5906065226840117876",
|
||||||
|
"access_logs.0.bucket_prefix": "",
|
||||||
|
"access_logs.0.enabled": "true",
|
||||||
|
"access_logs.0.interval": "5",
|
||||||
|
"availability_zones.#": "3",
|
||||||
|
"availability_zones.2050015877": "us-west-2c",
|
||||||
|
"availability_zones.221770259": "us-west-2b",
|
||||||
|
"availability_zones.2487133097": "us-west-2a",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
Config: map[string]interface{}{
|
||||||
|
"availability_zones": []interface{}{"us-west-2a", "us-west-2b", "us-west-2c"},
|
||||||
|
},
|
||||||
|
|
||||||
|
Diff: &terraform.InstanceDiff{
|
||||||
|
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||||
|
"access_logs.#": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "1",
|
||||||
|
New: "0",
|
||||||
|
NewRemoved: false,
|
||||||
|
},
|
||||||
|
"access_logs.0.bucket": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "terraform-access-logs-bucket-5906065226840117876",
|
||||||
|
New: "",
|
||||||
|
NewRemoved: true,
|
||||||
|
},
|
||||||
|
"access_logs.0.bucket_prefix": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "",
|
||||||
|
New: "",
|
||||||
|
NewRemoved: true,
|
||||||
|
},
|
||||||
|
"access_logs.0.enabled": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "",
|
||||||
|
New: "",
|
||||||
|
NewRemoved: true,
|
||||||
|
},
|
||||||
|
"access_logs.0.interval": &terraform.ResourceAttrDiff{
|
||||||
|
Old: "5",
|
||||||
|
New: "60",
|
||||||
|
NewRemoved: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tc := range cases {
|
for i, tc := range cases {
|
||||||
|
Loading…
Reference in New Issue
Block a user