diff --git a/gen/definitions/classes.yaml b/gen/definitions/classes.yaml index 4dc055ad4..30504ae9e 100644 --- a/gen/definitions/classes.yaml +++ b/gen/definitions/classes.yaml @@ -52,8 +52,6 @@ fvAEPg: relation_fv_rs_aepg_mon_pol: relation_to_application_epg_monitoring_policy.monitoring_policy_name fvRsIntraEpg: relation_fv_rs_intra_epg: relation_to_intra_epg_contracts.contract_name - fvRsPathAtt: - relation_fv_rs_path_att: relation_to_static_paths.target_dn fvRsNodeAtt: relation_fv_rs_node_att: relation_to_static_leafs node_dn: relation_to_static_leafs.target_dn @@ -128,7 +126,6 @@ qosDot1PClass: - "Tenants -> Policies -> Protocol -> Custom QoS -> Dot1p Classifiers" sub_category: "Tenant Policies" - fhsTrustCtrlPol: ui_locations: - "Tenants -> Policies -> Protocol -> First Hop Security -> Trust Control Policies" @@ -729,8 +726,6 @@ fvBD: flt_type: relation_to_netflow_monitor_policies.filter_type fvRsBDToOut: relation_fv_rs_bd_to_out: relation_to_l3_outsides.l3_outside_name - fvRsBDToProfile: - relation_fv_rs_bd_to_profile: relation_to_route_control_profile.route_control_profile_name fvRsBDToRelayP: relation_fv_rs_bd_to_relay_p: relation_to_dhcp_relay_policy.dhcp_relay_policy_name fvRsCtx: diff --git a/gen/definitions/properties.yaml b/gen/definitions/properties.yaml index d605a9161..618607375 100644 --- a/gen/definitions/properties.yaml +++ b/gen/definitions/properties.yaml @@ -463,8 +463,21 @@ fvRsScope: parents: - class_name: "fvESg" parent_dependency: "fvAp" - - class_name: "fvAEPg" - parent_dependency: "fvAp" + targets: + - class_name: "fvCtx" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/ctx-vrf_name_1" + relation_resource_name: "vrf" + properties: + name: "vrf_name_1" + - class_name: "fvCtx" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/ctx-vrf_name_0" + relation_resource_name: "vrf" + properties: + name: "vrf_name_0" fvRsCons: ignores: @@ -476,6 +489,23 @@ fvRsCons: parent_dependency: "fvAp" - class_name: "fvAEPg" parent_dependency: "fvAp" + targets: + - class_name: "vzBrCP" + shared_classes: + - "fvRsProv" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/brc-contract_name_0" + relation_resource_name: "contract" + properties: + name: "contract_name_0" + - class_name: "vzBrCP" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/brc-contract_name_1" + relation_resource_name: "contract" + properties: + name: "contract_name_1" fvRsProv: ignores: @@ -487,6 +517,7 @@ fvRsProv: parent_dependency: "fvAp" - class_name: "fvAEPg" parent_dependency: "fvAp" + fvRsConsIf: ignore_custom_type_docs: @@ -496,6 +527,21 @@ fvRsConsIf: parent_dependency: "fvAp" - class_name: "fvAEPg" parent_dependency: "fvAp" + targets: + - class_name: "vzCPIf" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/cif-imported_contract_name_0" + relation_resource_name: "imported_contract" + properties: + name: "imported_contract_name_0" + - class_name: "vzCPIf" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/cif-imported_contract_name_1" + relation_resource_name: "imported_contract" + properties: + name: "imported_contract_name_1" fvRsProtBy: parents: @@ -503,6 +549,21 @@ fvRsProtBy: parent_dependency: "fvAp" - class_name: "fvAEPg" parent_dependency: "fvAp" + targets: + - class_name: "vzTaboo" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/taboo-taboo_contract_name_0" + relation_resource_name: "taboo_contract" + properties: + name: "taboo_contract_name_0" + - class_name: "vzTaboo" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/taboo-taboo_contract_name_1" + relation_resource_name: "taboo_contract" + properties: + name: "taboo_contract_name_1" fvRsIntraEpg: documentation: @@ -543,17 +604,17 @@ fvRsSecInherited: - class_name: "fvAEPg" parent_dependency: "fvAp" overwrite_parent_dn_key: "application_profile_dn" - target_dn: "uni/tn-test_tenant/ap-test_ap/epg-epg_2" + target_dn: "uni/tn-test_tenant/ap-test_ap/epg-epg_0" relation_resource_name: "contract_master" properties: - name: "epg_2" + name: "epg_0" - class_name: "fvAEPg" parent_dependency: "fvAp" overwrite_parent_dn_key: "application_profile_dn" - target_dn: "uni/tn-test_tenant/ap-test_ap/epg-epg_3" + target_dn: "uni/tn-test_tenant/ap-test_ap/epg-epg_1" relation_resource_name: "contract_master" properties: - name: "epg_3" + name: "epg_1" fvCrtrn: overwrites: @@ -767,6 +828,50 @@ fvAEPg: fvRsAEPgMonPol: documentation: tnMonEPGPolName: "The name of the monitoring policy." + targets: + - class_name: "monEPGPol" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/monepg-monitoring_policy_name_1" + relation_resource_name: "monitoring_policy" + properties: + name: "monitoring_policy_name_1" + +fvRsCustQosPol: + targets: + - class_name: "qosCustomPol" + parent_dependency: "fvTenant" + target_dn: "uni/tn-test_tenant/qoscustom-custom_qos_policy_name_1" + relation_resource_name: "custom_qos_policy" + properties: + name: "custom_qos_policy_name_1" + +fvRsTrustCtrl: + targets: + - class_name: "fhsTrustCtrlPol" + parent_dependency: "fvTenant" + target_dn: "uni/tn-test_tenant/trustctrlpol-trust_control_policy_name_1" + relation_resource_name: "trust_control_policy" + properties: + name: "trust_control_policy_name_1" + +fvRsDppPol: + targets: + - class_name: "qosDppPol" + parent_dependency: "fvTenant" + target_dn: "uni/tn-test_tenant/qosdpppol-data_plane_policing_policy_name_1" + relation_resource_name: "data_plane_policing_policy" + properties: + name: "data_plane_policing_policy_name_1" + +fvRsBd: + targets: + - class_name: "fvBD" + parent_dependency: "fvTenant" + target_dn: "uni/tn-test_tenant/BD-bridge_domain_name_1" + relation_resource_name: "bridge_domain_name" + properties: + name: "bridge_domain_name_1" fvRsFcPathAtt: default_values: @@ -1448,6 +1553,11 @@ fvBD: endpoint_move_detection_mode: "garp" l2_unknown_unicast_flooding: "proxy" limit_ip_learn_to_subnets: "yes" + legacy: + custom_mac_address: "00:22:BD:F8:19:FE" + virtual_mac_address: "00:22:BD:F8:19:FB" + link_local_ipv6_address: "fe80::1" + unicast_routing: "yes" parents: - class_name: "fvTenant" parent_dependency: "" @@ -1458,6 +1568,14 @@ fvRsABDPolMonPol: relation_from_bridge_domain_to_monitoring_policy: "relation_to_monitor_policy" documentation: tnMonEPGPolName: "The name of the Monitoring Policy object." + targets: + - class_name: "monEPGPol" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/monepg-monitoring_policy_name_1" + relation_resource_name: "monitoring_policy" + properties: + name: "monitoring_policy_name_1" fvRsBdToEpRet: overwrites: @@ -1466,18 +1584,40 @@ fvRsBdToEpRet: documentation: tnFvEpRetPolName: "The name of the Endpoint Retention Policy object." resolveAct: "The action to take for resolving the Endpoint Retention Policy object." + targets: + - class_name: "fvEpRetPol" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/epRPol-end_point_retention_policy_name_1" + relation_resource_name: "end_point_retention_policy" + properties: + name: "end_point_retention_policy_name_1" fvRsBDToFhs: overwrites: relation_from_bridge_domain_to_first_hop_security_policy: "relation_to_first_hop_security_policy" documentation: tnFhsBDPolName: "The name of the First Hop Security Policy object." + targets: + - class_name: "fhsBDPol" + parent_dependency: "fvTenant" + target_dn: "uni/tn-test_tenant/bdpol-first_hop_security_policy_name_1" + relation_resource_name: "first_hop_security_policy" + properties: + name: "first_hop_security_policy_name_1" fvRsBDToNdP: overwrites: relation_from_bridge_domain_to_neighbor_discovery_interface_policy: "relation_to_neighbor_discovery_interface_policy" documentation: tnNdIfPolName: "The name of the Neighbor Discovery Interface Policy object." + targets: + - class_name: "ndIfPol" + parent_dependency: "fvTenant" + target_dn: "uni/tn-test_tenant/ndifpol-neighbor_discovery_interface_policy_name_1" + relation_resource_name: "neighbor_discovery_interface_policy" + properties: + name: "neighbor_discovery_interface_policy_name_1" fvRsBDToNetflowMonitorPol: overwrites: @@ -1501,6 +1641,13 @@ fvRsBDToNetflowMonitorPol: - class_name: "fvBD" parent_dependency: "fvTenant" parent_dn: "aci_bridge_domain.test.id" + targets: + - class_name: "netflowMonitorPol" + parent_dependency: "fvTenant" + target_dn: "uni/tn-test_tenant/monitorpol-netflow_monitor_policy_name_1" + relation_resource_name: "netflow_monitor_policy_name" + properties: + name: "netflow_monitor_policy_name_1" fvRsBDToOut: overwrites: @@ -1513,12 +1660,51 @@ fvRsBDToOut: fvRsBDToProfile: overwrites: relation_from_bridge_domain_to_route_control_profile: "relation_to_route_control_profile" + targets: + - class_name: "fvCtx" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/ctx-vrf_name_1" + relation_resource_name: "vrf" + properties: + name: "vrf_name_1" + - class_name: "l3extOut" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/out-abr_l3_outside_name_1" + relation_resource_name: "l3_outside" + properties: + name: "l3_outside_name_1" + relation_l3ext_rs_ectx: aci_vrf.test_vrf_0.id + - class_name: "l3extOut" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/out-abr_l3_outside_name_0" + relation_resource_name: "l3_outside" + properties: + name: "l3_outside_name_0" + relation_l3ext_rs_ectx: aci_vrf.test_vrf_0.id + - class_name: "rtctrlProfile" + parent_dependency: "l3extOut" + target_dn: "uni/tn-test_tenant/out-abr_l3_outside_name_0/prof-route_control_profile_name_1" + parent_dependency_dn_ref: aci_l3_outside.test_l3_outside_0.id + relation_resource_name: "route_control_profile" + properties: + name: "route_control_profile_name_1" fvRsBDToRelayP: overwrites: relation_from_bridge_domain_to_dhcp_relay_policy: "relation_to_dhcp_relay_policy" documentation: tnDhcpRelayPName: "The name of the DHCP Relay Policy object." + targets: + - class_name: "dhcpRelayP" + parent_dependency: "fvTenant" + overwrite_parent_dn_key: "tenant_dn" + target_dn: "uni/tn-test_tenant/relayp-dhcp_relay_policy_name_1" + relation_resource_name: "dhcp_relay_policy" + properties: + name: "dhcp_relay_policy_name_1" fvRsCtx: documentation: @@ -1527,10 +1713,24 @@ fvRsCtx: fvRsIgmpsn: documentation: tnIgmpSnoopPolName: "The name of the IGMP Snooping Policy object." + targets: + - class_name: "igmpSnoopPol" + parent_dependency: "fvTenant" + target_dn: "uni/tn-test_tenant/snPol-igmp_snooping_policy_name_1" + relation_resource_name: "igmp_snooping_policy" + properties: + name: "igmp_snooping_policy_name_1" fvRsMldsn: documentation: tnMldSnoopPolName: "The name of the MLD Snooping Policy object." + targets: + - class_name: "mldSnoopPol" + parent_dependency: "fvTenant" + target_dn: "uni/tn-test_tenant/mldsnoopPol-mld_snooping_policy_name_1" + relation_resource_name: "mld_snooping_policy" + properties: + name: "mld_snooping_policy_name_1" fvRogueExceptionMac: test_values: diff --git a/gen/generator.go b/gen/generator.go index 6702ea28e..90886e7ea 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -142,6 +142,137 @@ var templateFuncs = template.FuncMap{ "addToChild": AddToChildInTestTemplate, "checkDeletableChild": CheckDeletableChild, "emptyChild": EmptyChild, + "excludeForNullInSetCheck": ExcludeForNullInSetCheck, + "getTestTargetValue": GetTestTargetValue, + "isReference": IsReference, + "getLegacyPropertyTestValue": GetTestValue, + "getLegacyBlockTestValue": GetBlockTestValue, +} + +func getChildTarget(model Model, childKey, childValue string, tDn bool) string { + + for index, childDependency := range model.ChildTestDependencies { + targetResourceName := childDependency.TargetResourceName + if !tDn { + if childKey == fmt.Sprintf("%s_name", targetResourceName) { + childKey = "name" + } + if result, ok := childDependency.Properties[childKey]; ok && childValue == result { + return fmt.Sprintf(`aci_%s.test_%s_%d.id`, targetResourceName, targetResourceName, index%2) + } + } else { + if childDependency.Source == childKey || DefinedInList(childDependency.SharedClasses, childKey) { + if !childDependency.Static { + return fmt.Sprintf(`aci_%s.test_%s_%d.id`, targetResourceName, targetResourceName, index%2) + } else { + return childDependency.TargetDn + } + } + } + } + return childValue +} + +func GetBlockTestValue(className, attributeName string, model Model) string { + for _, child := range model.Children { + if child.PkgName == className { + if attributeName == "TargetDn" { + return getChildTarget(model, className, "target_dn_2", true) + } + for _, property := range child.Properties { + if property.Name == attributeName { + if len(property.ValidValues) > 0 { + childKey := GetOverwriteAttributeName(model.PkgName, property.SnakeCaseName, model.Definitions) + return GetOverwriteAttributeValue(child.PkgName, childKey, property.ValidValues[0], "legacy", 0, model.Definitions).(string) + } else if property.PropertyName == "tDn" { + return getChildTarget(model, className, "target_dn_1", true) + } + childKey := GetOverwriteAttributeName(child.PkgName, property.SnakeCaseName, model.Definitions) + childValue := GetOverwriteAttributeValue(child.PkgName, childKey, fmt.Sprintf("%s_1", childKey), "default", 0, model.Definitions).(string) + return getChildTarget(model, childKey, childValue, false) + } + } + } + } + return attributeName +} + +func GetTestValue(name string, model Model) string { + + for _, property := range model.Properties { + if property.Name == name { + childKey := GetOverwriteAttributeName(model.PkgName, property.SnakeCaseName, model.Definitions) + if len(property.ValidValues) > 0 { + return GetOverwriteAttributeValue(model.PkgName, childKey, property.ValidValues[0], "legacy", 0, model.Definitions).(string) + } + return GetOverwriteAttributeValue(model.PkgName, childKey, fmt.Sprintf("%s_1", childKey), "legacy", 0, model.Definitions).(string) + } + } + + for _, child := range model.Children { + if Capitalize(child.PkgName) == name { + properties := []string{} + for _, property := range child.Properties { + if strings.HasSuffix(property.PropertyName, "Name") { + childKey := GetOverwriteAttributeName(child.PkgName, property.SnakeCaseName, model.Definitions) + childValue := GetOverwriteAttributeValue(child.PkgName, childKey, fmt.Sprintf("%s_1", childKey), "default", 0, model.Definitions).(string) + properties = append(properties, getChildTarget(model, childKey, childValue, false)) + } else if property.PropertyName == "tDn" { + return getChildTarget(model, child.PkgName, "target_dn_0", true) + } + } + // If there are multiple properties that has suffix of Name, return the one that matches the child resource name + if len(properties) > 1 { + for _, property := range properties { + if strings.Contains(property, string(child.ChildResourceName[strings.Index(child.ChildResourceName, "_to_")+4])) { + return property + } + } + } else if len(properties) == 1 { + return properties[0] + } + } + } + if name == "ParentDn" { + if len(model.ContainedBy) > 0 { + parentResource := GetResourceName(model.ContainedBy[0], model.Definitions) + return fmt.Sprintf(`aci_%s.test.id`, parentResource) + } + } + return name +} + +func GetTestTargetValue(targets []interface{}, key, value string) string { + + for index, target := range targets { + + var resourceName string + if targetResourceName, ok := target.(map[interface{}]interface{})["target_resource_name"]; ok { + resourceName = targetResourceName.(string) + } + + if properties, ok := target.(map[interface{}]interface{})["properties"]; ok { + + if key == fmt.Sprintf("%s_name", resourceName) { + key = "name" + } + if result, ok := properties.(map[interface{}]interface{})[key]; ok && value == result { + return fmt.Sprintf(`aci_%s.test_%s_%d.%s`, resourceName, resourceName, index%2, key) + } + } + } + return value +} + +func ExcludeForNullInSetCheck(resourceClassName string) bool { + // Function to exclude TagTag and TagAnnotation from the null check in the Set function + // Done to reduce the amount of functions created which are not needed for these classes + // During refactor to struct per class which is reused in children this is not needed anymore + var childClasses []string + for _, child := range alwaysIncludeChildren { + childClasses = append(childClasses, Capitalize(strings.ReplaceAll(child, ":", ""))) + } + return !slices.Contains(childClasses, resourceClassName) } func ContainsRequired(properties map[string]Property) bool { @@ -409,6 +540,10 @@ func ContainsString(s, sub string) bool { return strings.Contains(s, sub) } +func IsReference(s string) bool { + return strings.HasPrefix(s, "aci_") || strings.HasPrefix(s, "data.aci_") +} + // Reused from https://github.com/buxizhizhoum/inflection/blob/master/inflection.go#L8 to avoid importing the whole package func Underscore(s string) string { for _, reStr := range []string{`([A-Z]+)([A-Z][a-z])`, `([a-z\d])([A-Z])`} { @@ -1241,6 +1376,8 @@ type TypeChange struct { } type TestDependency struct { + Source string + SharedClasses interface{} ClassName string ParentDependency string ParentDependencyDnRef string @@ -2687,7 +2824,7 @@ func (m *Model) SetModelTestDependencies(classModels map[string]Model, definitio for index, v := range value.([]interface{}) { targetMap := v.(map[interface{}]interface{}) if className, ok := targetMap["class_name"]; ok { - testDependencies = append(testDependencies, getTestDependency(className.(string), targetMap, definitions, index)) + testDependencies = append(testDependencies, getTestDependency(m.PkgName, className.(string), targetMap, definitions, index)) } } } @@ -2702,7 +2839,7 @@ func (m *Model) SetModelTestDependencies(classModels map[string]Model, definitio for index, v := range value.([]interface{}) { targetMap := v.(map[interface{}]interface{}) if className, ok := targetMap["class_name"]; ok && !slices.Contains(m.getExcludeTargets(), className.(string)) { - childTestDependencies = append(childTestDependencies, getTestDependency(className.(string), targetMap, definitions, index)) + childTestDependencies = append(childTestDependencies, getTestDependency(child, className.(string), targetMap, definitions, index)) } } } @@ -2729,9 +2866,10 @@ func (m *Model) getExcludeTargets() []string { return excludeTargets } -func getTestDependency(className string, targetMap map[interface{}]interface{}, definitions Definitions, index int) TestDependency { +func getTestDependency(sourceClassName, className string, targetMap map[interface{}]interface{}, definitions Definitions, index int) TestDependency { testDependency := TestDependency{} + testDependency.Source = sourceClassName testDependency.ClassName = className testDependency.TargetResourceName = GetResourceName(className, definitions) testDependency.RelationResourceName = testDependency.TargetResourceName @@ -2741,9 +2879,17 @@ func getTestDependency(className string, targetMap map[interface{}]interface{}, testDependency.RelationResourceName = relationResourceName.(string) } + if sharedClasses, ok := targetMap["shared_classes"]; ok { + testDependency.SharedClasses = sharedClasses + } + if parentDependency, ok := targetMap["parent_dependency"]; ok { testDependency.ParentDependency = parentDependency.(string) - testDependency.ParentDependencyDnRef = fmt.Sprintf("%s_%s.test.id", providerName, GetResourceName(parentDependency.(string), definitions)) + if parentDependencyDn, ok := targetMap["parent_dependency_dn_ref"]; ok { + testDependency.ParentDependencyDnRef = parentDependencyDn.(string) + } else { + testDependency.ParentDependencyDnRef = fmt.Sprintf("%s_%s.test.id", providerName, GetResourceName(parentDependency.(string), definitions)) + } } if targetDn, ok := targetMap["target_dn"]; ok { diff --git a/gen/templates/resource.go.tmpl b/gen/templates/resource.go.tmpl index a2003e526..105cf7cac 100644 --- a/gen/templates/resource.go.tmpl +++ b/gen/templates/resource.go.tmpl @@ -9,8 +9,6 @@ import ( "context" "fmt" "encoding/json" - "reflect" - "strings" "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" @@ -206,6 +204,15 @@ type {{ capitalize .ClassName }}{{$.ResourceClassName}}ResourceModelV{{$.LegacyS {{ .Name }} types.{{getMigrationType .ValueType}} `tfsdk:"{{.AttributeName}}"` {{- end}} } + +func getEmpty{{ capitalize .ClassName }}{{$.ResourceClassName}}ResourceModelV{{$.LegacySchemaVersion}}() {{ capitalize .ClassName }}{{$.ResourceClassName}}ResourceModelV{{$.LegacySchemaVersion}} { + return {{ capitalize .ClassName }}{{$.ResourceClassName}}ResourceModelV{{$.LegacySchemaVersion}}{ + {{- range .Attributes}} + {{ .Name }}: basetypes.NewStringNull(), + {{- end}} + } +} + {{ end}} func (r *{{.ResourceClassName}}Resource) UpgradeState(ctx context.Context) map[int64]resource.StateUpgrader { @@ -657,8 +664,11 @@ func set{{ .ResourceClassName }}LegacyAttributes(ctx context.Context, diags *dia data.Deprecated{{.ResourceClassName}} = basetypes.NewStringNull() {{- else if eq $childClassType "set,string" }} Deprecated{{.ResourceClassName}}{{$.ResourceClassName}}List := make([]string, 0) + {{- else if eq $childClassType "block,set" }} + Deprecated{{.ResourceClassName}}{{$.ResourceClassName}}List := make([]{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModelV1, 0) {{- end }} - {{- end }}{{- end }} + {{- end }} + {{- end }} _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -666,55 +676,80 @@ func set{{ .ResourceClassName }}LegacyAttributes(ctx context.Context, diags *dia for _, child := range children { for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) - {{- range .Children}}{{- if isLegacyChild .PkgName $.LegacyChildren}}{{$ResourceName := .ResourceName}} - {{- $childClassType := getValueFromMap .PkgName $.MigrationClassTypes}}{{- if eq $childClassType "string" }} + {{- range .Children}} + {{- if isLegacyChild .PkgName $.LegacyChildren}}{{$ResourceName := .ResourceName}} + {{- $childClassType := getValueFromMap .PkgName $.MigrationClassTypes}} + {{- if eq $childClassType "string" }} if childClassName == "{{ .PkgName }}" { for childAttributeName, childAttributeValue := range childAttributes { - {{- range .Properties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if and (eq $AttributeName (capitalize .PkgName)) (isNewNamedClassAttributeMatch $Overwrite $ResourceName)}} + {{- range .Properties}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} + {{- if and (eq $AttributeName (capitalize .PkgName)) (isNewNamedClassAttributeMatch $Overwrite $ResourceName)}} if childAttributeName == "tDn" { data.Deprecated{{.ResourceClassName}} = basetypes.NewStringValue(childAttributeValue.(string)) } - {{- else if and (ne $AttributeName "") (isNewNamedClassAttributeMatch $Overwrite $ResourceName)}} + {{- else if and (ne $AttributeName "") (isNewNamedClassAttributeMatch $Overwrite $ResourceName)}} if childAttributeName == "{{.PropertyName}}" { data.Deprecated{{.ResourceClassName}} = basetypes.NewStringValue(childAttributeValue.(string)) } + {{- end}} {{- end}} - {{- end}} } } - {{- else if eq $childClassType "set,string" }} + {{- else if eq $childClassType "set,string" }} if childClassName == "{{ .PkgName }}" { for childAttributeName, childAttributeValue := range childAttributes { - {{- range .Properties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if eq $AttributeName (capitalize .PkgName)}} + {{- range .Properties}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} + {{- if eq $AttributeName (capitalize .PkgName)}} if childAttributeName == "tDn" && childAttributeValue != "" && !ContainsString(Deprecated{{.ResourceClassName}}{{$.ResourceClassName}}List, childAttributeValue.(string)) { Deprecated{{.ResourceClassName}}{{$.ResourceClassName}}List = append(Deprecated{{.ResourceClassName}}{{$.ResourceClassName}}List, childAttributeValue.(string)) }{{break}} - {{- else if ne $AttributeName ""}} + {{- else if ne $AttributeName ""}} if childAttributeName == "{{.PropertyName}}" { Deprecated{{.ResourceClassName}}{{$.ResourceClassName}}List = append(Deprecated{{.ResourceClassName}}{{$.ResourceClassName}}List, childAttributeValue.(string)) } // {{$AttributeName}} + {{- end}} + {{- end}} + } + } + {{- else if eq $childClassType "block,set" }} + if childClassName == "{{ .PkgName }}" { + Deprecated{{.ResourceClassName}}{{$.ResourceClassName}} := getEmpty{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModelV1() + for childAttributeName, childAttributeValue := range childAttributes { + {{- range .Properties}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} + {{- if eq $AttributeName "TargetDn"}} + if childAttributeName == "tDn" { + Deprecated{{.ResourceClassName}}{{$.ResourceClassName}}.TargetDn = basetypes.NewStringValue(childAttributeValue.(string)) + } + {{- else if isNewNamedClassAttribute $Overwrite}} + if childAttributeName == "tDn" { + Deprecated{{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}} = basetypes.NewStringValue(childAttributeValue.(string)) + } + {{- else if ne .Name "Annotation"}} + if childAttributeName == "{{.PropertyName}}" { + Deprecated{{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}} = basetypes.NewStringValue(childAttributeValue.(string)) + } + {{- end}} {{- end}} - {{- end}} } + Deprecated{{.ResourceClassName}}{{$.ResourceClassName}}List = append(Deprecated{{.ResourceClassName}}{{$.ResourceClassName}}List, Deprecated{{.ResourceClassName}}{{$.ResourceClassName}}) } + {{- end }} + {{- end }} {{- end }} - {{- end }}{{- end }} } } {{- range .Children}}{{- if isLegacyChild .PkgName $.LegacyChildren}} {{- $childClassType := getValueFromMap .PkgName $.MigrationClassTypes}} - {{- if eq $childClassType "set,string" }} + {{- if or (eq $childClassType "set,string") (eq $childClassType "block,set") }} {{ .PkgName }}Set, _ := types.SetValueFrom(ctx, data.Deprecated{{ .ResourceClassName }}.ElementType(ctx), Deprecated{{.ResourceClassName}}{{$.ResourceClassName}}List) data.Deprecated{{ .ResourceClassName }} = {{ .PkgName }}Set - {{- else if eq $childClassType "block,set" }} - data.Deprecated{{ .ResourceClassName }} = types.SetNull(deprecated{{ .ResourceClassName }}Type) {{- end}} {{- end}}{{- end}} } @@ -743,24 +778,24 @@ func (r *{{.ResourceClassName}}Resource) ModifyPlan(ctx context.Context, req res return } } - {{- range .Children}} - {{- if containsSingleNestedChildren .Children}} - {{- template "declareChildListsInGetandSetAttributesFunctionWithGetEmpty" . }} - {{- if or (not .IdentifiedBy) .MaxOneClassAllowed}} + {{- range .Children}} + {{- if containsSingleNestedChildren .Children}} + {{- template "declareChildListsInGetandSetAttributesFunctionWithGetEmpty" . }} + {{- if or (not .IdentifiedBy) .MaxOneClassAllowed}} var {{ .ResourceClassName }}ConfigData {{.ResourceClassName}}{{.ParentHierarchy}}ResourceModel configData.{{ .ResourceClassName }}.As(ctx, &{{ .ResourceClassName }}ConfigData, basetypes.ObjectAsOptions{}) - {{- else}} + {{- else}} var {{ .ResourceClassName }}ConfigData []{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModel configData.{{ .ResourceClassName }}.ElementsAs(ctx, &{{ .ResourceClassName }}ConfigData, false) + {{- end}} + {{- $resource := . }} + {{- range .Children}} + {{- $newCtx := addToTemplateProperties . "configData" $resource -}} + {{- template "modifyPlanForSingleNestedChildren" $newCtx }} + {{- end}} + {{- end}} {{- end}} - {{- $resource := . }} {{- range .Children}} - {{- $newCtx := addToTemplateProperties . "configData" $resource -}} - {{- template "modifyPlanForSingleNestedChildren" $newCtx }} - {{- end}} - {{- end}} - {{- end}} - {{- range .Children}} {{- if or (not .IdentifiedBy) .MaxOneClassAllowed}} if !configData.{{ .ResourceClassName }}.IsNull() && stateData != nil { if IsEmptySingleNestedAttribute(configData.{{ .ResourceClassName }}.Attributes()) { @@ -775,112 +810,74 @@ func (r *{{.ResourceClassName}}Resource) ModifyPlan(ctx context.Context, req res planData.{{.ResourceClassName}} = {{.ResourceClassName}}Object } {{- end}} } - {{- else}} - {{- if containsSingleNestedChildren .Children}} + {{- else}} + {{- if containsSingleNestedChildren .Children}} {{.ResourceClassName}}Set, _ := types.SetValueFrom(ctx, {{ .ResourceClassName }}Type, {{ .ResourceClassName }}{{.ParentHierarchy}}List[0]) planData.{{.ResourceClassName}} = {{.ResourceClassName}}Set - {{- end}} {{- end}} + {{- end}} {{- end}} {{ if .LegacyAttributes}}{{ $ResourceClassName := .ResourceClassName}} - {{ range .LegacyAttributes}}{{$SetName := .Name}} - {{- if and (ne .ReplacedBy.AttributeName "") (eq (getMigrationType .ValueType) "String") (isNewAttributeStringType .ReplacedBy.AttributeName) }} - {{- if .NeedsCustomType}} - if !configData.{{ .Name }}.IsNull() { - {{- range $.Properties}} - {{- if eq .Name $SetName}} - matchMap := map[string]string{ - {{- range $key, $value := .ValidValuesMap}} - "{{$key}}": "{{$value}}", - {{- end}} - } - {{- end}} - {{- end}} - if configData{{ .Name }}, ok := matchMap[configData.{{ .Name }}.ValueString()]; ok { - planData.Deprecated{{ .Name }} = basetypes.NewStringValue(configData{{ .Name }}) - } else { - planData.Deprecated{{ .Name }} = configData.{{ .Name }}.StringValue - } - } else if !configData.Deprecated{{ .Name }}.IsNull() { - planData.{{ .Name }} =customTypes.{{$ResourceClassName}}{{.Name}}StringValue{ StringValue: configData.Deprecated{{ .Name }} } - } else if stateData != nil { // used to replace use state for unknown - planData.Deprecated{{ .Name }} = stateData.Deprecated{{ .Name }} - } - {{- else}} - if !configData.{{ .Name }}.IsNull() { - planData.Deprecated{{ .Name }} = configData.{{ .Name }} - } else if !configData.Deprecated{{ .Name }}.IsNull() { + {{ range .LegacyAttributes}}{{$SetName := .Name}} + {{- if and (ne .ReplacedBy.AttributeName "") (eq (getMigrationType .ValueType) "String") (isNewAttributeStringType .ReplacedBy.AttributeName) }} + if !configData.Deprecated{{ .Name }}.IsNull() { + {{- if .NeedsCustomType}} + planData.{{ .Name }} = customTypes.{{$ResourceClassName}}{{.Name}}StringValue{StringValue: configData.Deprecated{{ .Name }} } + {{- else}} planData.{{ .Name }} = configData.Deprecated{{ .Name }} - } else if stateData != nil { // used to replace use state for unknown - planData.Deprecated{{ .Name }} = stateData.Deprecated{{ .Name }} + {{- end}} } - {{- end}} - {{- else if and (ne .ReplacedBy.AttributeName "") (eq (getMigrationType .ValueType) "String") }} - {{- range $.Children}}{{$ResourceName := .ResourceName}} - {{- if or (not .IdentifiedBy) .MaxOneClassAllowed}} - {{- if eq $SetName (capitalize .PkgName)}} - if !configData.{{ $SetName }}.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.{{ $SetName }}.Attributes()) { - planData.{{ $SetName }} = configData.{{ $SetName }} - planData.Deprecated{{ $SetName }} = basetypes.NewStringNull() - } else { - var attributeValues {{$SetName}}{{$.ResourceClassName}}ResourceModel - configData.{{ $SetName }}.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - {{- range .Properties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if and (ne $AttributeName "") (isNewNamedClassAttributeMatch $Overwrite $ResourceName)}} - if GetMOName(stateData.Deprecated{{$SetName}}.ValueString()) == attributeValues.{{ .Name }}.ValueString() && !attributeValues.{{ .Name }}.IsNull() { - planData.Deprecated{{$SetName}} = stateData.Deprecated{{$SetName}} - } - {{- end}} - {{- end}} - } - } else if !configData.Deprecated{{ $SetName }}.IsNull() { + {{- else if and (ne .ReplacedBy.AttributeName "") (eq (getMigrationType .ValueType) "String") }} + {{- range $.Children}}{{$ResourceName := .ResourceName}} + {{- if or (not .IdentifiedBy) .MaxOneClassAllowed}} + {{- if eq $SetName (capitalize .PkgName)}} + if !configData.Deprecated{{ $SetName }}.IsNull() { var newAttributeValues {{ $SetName }}{{.ParentHierarchy}}ResourceModel - {{- range .Children}} - {{- if or (not .IdentifiedBy) .MaxOneClassAllowed}} + {{- range .Children}} + {{- if or (not .IdentifiedBy) .MaxOneClassAllowed}} {{ .ResourceClassName | decapitalize }}{{.ParentHierarchy}}Value, _ := types.ObjectValueFrom(ctx, {{ .ResourceClassName }}{{.ParentHierarchy}}Type, getEmpty{{ .ResourceClassName }}{{.ParentHierarchy}}ResourceModel()) - {{- else}} + {{- else}} {{ .ResourceClassName | decapitalize }}{{.ParentHierarchy}}Value, _ := types.SetValueFrom(ctx, {{ .ResourceClassName }}{{.ParentHierarchy}}Type, make([]{{ .ResourceClassName }}{{.ParentHierarchy}}ResourceModel, 0)) - {{- end}} - {{- end}} - {{- range .Properties}} - {{- if eq .Name "Annotation"}} - {{ .Name | decapitalize }}Value := planData.Annotation - {{- end}} - {{- end}} - if stateData != nil { + {{- end}} + {{- end}} + {{- range .Properties}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- if eq .Name "Annotation"}} + {{ .Name | decapitalize }}Value := planData.{{ .Name }} + {{- else if not (isNewNamedClassAttribute $Overwrite) }} + {{ .Name | decapitalize }}Value := basetypes.NewStringUnknown() + {{- end}} + {{- end}} + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.{{ $SetName }}.Attributes()) { stateData.{{ $SetName }}.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) - {{- range .Properties}} - {{- if eq .Name "Annotation"}} - {{ .Name | decapitalize }}Value = newAttributeValues.Annotation - {{- end}} - {{- end}} - {{- range .Children}} + {{- range .Properties}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- if not (isNewNamedClassAttribute $Overwrite) }} + {{ .Name | decapitalize }}Value = newAttributeValues.{{.Name}} + {{- end}} + {{- end}} + {{- range .Children}} {{ .ResourceClassName | decapitalize }}{{.ParentHierarchy}}Value = newAttributeValues.{{.ResourceClassName}} - {{- end}} + {{- end}} } - {{- range .Properties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if isNewNamedClassAttribute $Overwrite }} - {{- if isNewNamedClassAttributeMatch $Overwrite $ResourceName}} + {{- range .Properties}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} + {{- if isNewNamedClassAttribute $Overwrite }} + {{- if isNewNamedClassAttributeMatch $Overwrite $ResourceName}} {{ .Name | decapitalize }}Value := basetypes.NewStringUnknown() if !configData.Deprecated{{ $SetName }}.IsUnknown() { {{ .Name | decapitalize }}Value = basetypes.NewStringValue(GetMOName(configData.Deprecated{{ $AttributeName }}.ValueString())) } {{- end}} {{- end}} - {{- end}} + {{- end}} {{$SetName}} := {{$SetName}}{{$.ResourceClassName}}ResourceModel{ {{- range .Properties}} {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if eq .Name "Annotation"}} + {{- if or (eq .Name "Annotation") (eq $AttributeName "")}} {{ .Name }}: {{ .Name | decapitalize }}Value, - {{- else if eq $AttributeName ""}} - {{ .Name }}: basetypes.NewStringNull(), {{- else}} {{- if isNewNamedClassAttribute $Overwrite }} {{- if isNewNamedClassAttributeMatch $Overwrite $ResourceName}} @@ -899,88 +896,43 @@ func (r *{{.ResourceClassName}}Resource) ModifyPlan(ctx context.Context, req res } {{$SetName}}Object, _ := types.ObjectValueFrom(ctx, {{$SetName}}{{$.ResourceClassName}}Type, {{$SetName}}) planData.{{$SetName}} = {{$SetName}}Object - } else if stateData != nil { // used to replace use state for unknown - planData.Deprecated{{$SetName}} = stateData.Deprecated{{$SetName}} - } {{- end}} + } + {{- end}} {{- else}} {{- if isLegacyChild .PkgName $.LegacyChildren}} {{- if eq $SetName (capitalize .PkgName)}} - if !configData.{{ $SetName }}.IsNull() && stateData != nil { - var attributeValues []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel - configData.{{.ResourceClassName}}.ElementsAs(ctx, &attributeValues, false) - for _, attributeValue := range attributeValues { - {{- range .Properties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if ne $AttributeName ""}} - if GetMOName(stateData.Deprecated{{.ResourceClassName}}.ValueString()) == attributeValue.{{ .Name }}.ValueString() { - planData.Deprecated{{.ResourceClassName}} = stateData.Deprecated{{.ResourceClassName}} - } - {{- end}} - {{- end}} - } - } else if !configData.Deprecated{{ $SetName }}.IsNull() { + if !configData.Deprecated{{ $SetName }}.IsNull() { {{.ResourceClassName}}List := make([]{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel, 0) {{.ResourceClassName}} := {{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel{ - {{- range .Properties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if eq .Name "Annotation"}} + {{- range .Properties}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} + {{- if eq .Name "Annotation"}} {{ .Name }}: planData.Annotation, - {{- else if eq $AttributeName ""}} + {{- else if eq $AttributeName ""}} {{ .Name }}: basetypes.NewStringNull(), - {{- else}} + {{- else}} {{ .Name }}: {{- if isNewNamedClassAttribute $Overwrite }}basetypes.NewStringValue(GetMOName(configData.Deprecated{{ $AttributeName }}.ValueString())){{- else }}configData.Deprecated{{ .Name }}{{- end }}, + {{- end}} {{- end}} - {{- end}} } {{.ResourceClassName}}List = append({{.ResourceClassName}}List, {{.ResourceClassName}}) {{.ResourceClassName}}Set, _ := types.SetValueFrom(ctx, {{.ResourceClassName}}{{.ParentHierarchy}}Type, {{.ResourceClassName}}List) planData.{{.ResourceClassName}} = {{.ResourceClassName}}Set - } else if stateData != nil { // used to replace use state for unknown - planData.Deprecated{{.ResourceClassName}} = stateData.Deprecated{{.ResourceClassName}} } + {{- end }} {{- end }} {{- end }} {{- end }} - {{- end }} - {{- else if ne .ReplacedBy.AttributeName "" }} - {{- range $.Children}} - {{- if isLegacyChild .PkgName $.LegacyChildren}} - {{- if eq $SetName (capitalize .PkgName)}} - if !configData.{{ $SetName }}.IsNull() && stateData != nil { - var attributeValues []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel - var newAttributeValues, stateAttributeValues []string - configData.{{.ResourceClassName}}.ElementsAs(ctx, &attributeValues, false) - stateData.Deprecated{{.ResourceClassName}}.ElementsAs(ctx, &stateAttributeValues, false) - for _, attributeValue := range attributeValues { - {{- range .Properties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if or (eq .Name "TDn") (isNewNamedClassAttribute $Overwrite)}} - newAttributeValues = append(newAttributeValues, attributeValue.{{ .Name }}.ValueString()) - {{- end }} - {{- end }} - } - - if len(newAttributeValues) == len(stateAttributeValues) { - allMatchState := true - for _, stateAttributeValue := range stateAttributeValues { - if !ContainsString(newAttributeValues, GetMOName(stateAttributeValue)) { - allMatchState = false - break - } - } - if allMatchState { - {{.ResourceClassName}}Set, _ := types.SetValueFrom(ctx, basetypes.StringType{}, stateAttributeValues) - planData.Deprecated{{.ResourceClassName}} = {{.ResourceClassName}}Set - } - } - } else if !configData.Deprecated{{ $SetName }}.IsNull() { + {{- else if ne .ReplacedBy.AttributeName "" }} + {{- range $.Children}} + {{- if isLegacyChild .PkgName $.LegacyChildren}} + {{- if eq $SetName (capitalize .PkgName)}}{{$tDn := false}} + if !configData.Deprecated{{ $SetName }}.IsNull() { {{.ResourceClassName}}List := make([]{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel, 0) var attributeValues []basetypes.StringValue var newAttributeValues []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel - configData.Deprecated{{.ResourceClassName}}.ElementsAs(ctx, &attributeValues, false) + planData.Deprecated{{.ResourceClassName}}.ElementsAs(ctx, &attributeValues, false) if stateData != nil { stateData.{{.ResourceClassName}}.ElementsAs(ctx, &newAttributeValues, false) } @@ -988,76 +940,76 @@ func (r *{{.ResourceClassName}}Resource) ModifyPlan(ctx context.Context, req res {{.ResourceClassName}}Value := {{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel{} foundAttributeValue := false for _, newAttributeValue := range newAttributeValues { - {{- range .Properties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if or (eq .Name "TDn") (isNewNamedClassAttribute $Overwrite)}} + {{- range .Properties}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} + {{- if or (eq .Name "TDn") (isNewNamedClassAttribute $Overwrite)}} if newAttributeValue.{{ .Name }}.ValueString() == {{- if isNewNamedClassAttribute $Overwrite }}GetMOName(attributeValue.ValueString()){{- else}}attributeValue.ValueString(){{- end}} { {{.ResourceClassName}}Value = newAttributeValue foundAttributeValue = true break } - {{- end}} - {{- end}} + {{- end}} + {{- end}} } - {{- range .Properties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if or (eq .Name "TDn") (isNewNamedClassAttribute $Overwrite)}} + {{- range .Properties}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} + {{- if or (eq .Name "TDn") (isNewNamedClassAttribute $Overwrite)}} {{ .Name | decapitalize}}Value := basetypes.NewStringUnknown() if !attributeValue.IsUnknown(){ {{ .Name | decapitalize }}Value = {{- if isNewNamedClassAttribute $Overwrite }}basetypes.NewStringValue(GetMOName(attributeValue.ValueString())){{- else}}basetypes.NewStringValue(attributeValue.ValueString()){{- end}} } - {{- end}} - {{- end}} + {{- end}} + {{- end}} {{ .ResourceClassName }} := {{ .ResourceClassName }}{{$.ResourceClassName}}ResourceModel { - {{- range .Properties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if or (eq .Name "TDn") (isNewNamedClassAttribute $Overwrite)}} + {{- range .Properties}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} + {{- if or (eq .Name "TDn") (isNewNamedClassAttribute $Overwrite)}} {{ .Name }}: {{ .Name | decapitalize }}Value, - {{- end}} - {{- end}} + {{- end}} + {{- end}} } if foundAttributeValue { - {{- range .Properties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if and (ne .Name "TDn") (not (isNewNamedClassAttribute $Overwrite))}} + {{- range .Properties}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} + {{- if and (ne .Name "TDn") (not (isNewNamedClassAttribute $Overwrite))}} {{ .ResourceClassName }}.{{ .Name }} = {{.ResourceClassName}}Value.{{ .Name }} - {{- end}} - {{- end}} + {{- end}} + {{- end}} } else { - {{- range .Properties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if eq .Name "Annotation"}} + {{- range .Properties}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} + {{- if eq .Name "Annotation"}} {{ .ResourceClassName }}.{{ .Name }} = planData.Annotation - {{- else if ne .DefaultValue ""}} - {{- if .HasCustomType}} - {{ .ResourceClassName }}.{{ .Name }} = customTypes.New{{.ResourceClassName}}{{.Name}}StringValue("{{ .DefaultValue }}") // Default to default value from meta when not found - {{- else}} - {{ .ResourceClassName }}.{{ .Name }} = basetypes.NewStringValue("{{ .DefaultValue }}") // Default to default value from meta when not found - {{- end}} - {{- end}} - {{- end}} + {{- else if ne .DefaultValue ""}} + {{- if .HasCustomType}} + {{ .ResourceClassName }}.{{ .Name }} = customTypes.New{{.ResourceClassName}}{{.Name}}StringUnknown() + {{- else}} + {{ .ResourceClassName }}.{{ .Name }} = basetypes.NewStringUnknown() + {{- end}} + {{- else if and (ne .Name "TDn") (not (isNewNamedClassAttribute $Overwrite))}} + {{ .ResourceClassName }}.{{ .Name }} = basetypes.NewStringUnknown() + {{- end}} + {{- end}} } - {{- $resourceClassName:= .ResourceClassName}} - {{- range .Children}} - {{- if or (not .IdentifiedBy) .MaxOneClassAllowed}} - {{ .ResourceClassName | decapitalize }}{{.ParentHierarchy}}Value, _ := types.ObjectValueFrom(ctx, {{ .ResourceClassName }}{{.ParentHierarchy}}Type, getEmpty{{ .ResourceClassName }}{{.ParentHierarchy}}ResourceModel()) - {{- else}} - {{ .ResourceClassName | decapitalize }}{{.ParentHierarchy}}Value, _ := types.SetValueFrom(ctx, {{ .ResourceClassName }}{{.ParentHierarchy}}Type, make([]{{ .ResourceClassName }}{{.ParentHierarchy}}ResourceModel, 0)) - {{- end}} - {{ $resourceClassName }}.{{.ResourceClassName}} = {{ .ResourceClassName | decapitalize }}{{.ParentHierarchy}}Value - {{- end}} + {{- $resourceClassName:= .ResourceClassName}} + {{- range .Children}} + {{- if or (not .IdentifiedBy) .MaxOneClassAllowed}} + {{ .ResourceClassName | decapitalize }}{{.ParentHierarchy}}Value, _ := types.ObjectValueFrom(ctx, {{ .ResourceClassName }}{{.ParentHierarchy}}Type, getEmpty{{ .ResourceClassName }}{{.ParentHierarchy}}ResourceModel()) + {{- else}} + {{ .ResourceClassName | decapitalize }}{{.ParentHierarchy}}Value, _ := types.SetValueFrom(ctx, {{ .ResourceClassName }}{{.ParentHierarchy}}Type, make([]{{ .ResourceClassName }}{{.ParentHierarchy}}ResourceModel, 0)) + {{- end}} + {{ $resourceClassName }}.{{.ResourceClassName}} = {{ .ResourceClassName | decapitalize }}{{.ParentHierarchy}}Value + {{- end}} {{.ResourceClassName}}List = append({{.ResourceClassName}}List, {{ .ResourceClassName }}) } {{.ResourceClassName}}Set, _ := types.SetValueFrom(ctx, {{.ResourceClassName}}{{.ParentHierarchy}}Type, {{.ResourceClassName}}List) planData.{{.ResourceClassName}} = {{.ResourceClassName}}Set - } else if stateData != nil { // used to replace use state for unknown - planData.Deprecated{{.ResourceClassName}} = stateData.Deprecated{{.ResourceClassName}} } {{- end }} {{- end }} @@ -1066,126 +1018,199 @@ func (r *{{.ResourceClassName}}Resource) ModifyPlan(ctx context.Context, req res {{ end }} {{ range .LegacyBlocks}}{{$ClassName := .ClassName}}{{$Attributes := .Attributes}} - planData.Deprecated{{ capitalize .ClassName }} = types.SetNull(deprecated{{ capitalize .ClassName }}Type) if !configData.Deprecated{{ capitalize .ClassName }}.IsNull() { {{- range $.Children}} {{- if isLegacyChild .PkgName $.LegacyChildren}} {{- if eq $ClassName .PkgName}} {{ .ResourceClassName }}List := make([]{{ .ResourceClassName }}{{$.ResourceClassName}}ResourceModel, 0) var attributeValues []{{ .ResourceClassName }}{{$.ResourceClassName}}ResourceModelV1 + {{- $NewProperties := getNewChildAttributes (getChildAttributesFromBlocks $ClassName $.LegacyBlocks) .Properties}} var newAttributeValues []{{ .ResourceClassName }}{{$.ResourceClassName}}ResourceModel - configData.Deprecated{{.ResourceClassName}}.ElementsAs(ctx, &attributeValues, false) - {{- range .Properties}} - {{- if eq .Name "Annotation"}} - {{ .Name | decapitalize }}Value := planData.Annotation - {{- end}} - {{- end}} if stateData != nil { stateData.{{.ResourceClassName}}.ElementsAs(ctx, &newAttributeValues, false) - for _, newAttributeValue := range newAttributeValues { - {{- range .Properties}} - {{- if eq .Name "Annotation"}} - {{ .Name | decapitalize }}Value = newAttributeValue.Annotation - {{- end}} - {{- end}} - } } + planData.Deprecated{{.ResourceClassName}}.ElementsAs(ctx, &attributeValues, false) for _, attributeValue := range attributeValues { - {{- $NewProperties := getNewChildAttributes (getChildAttributesFromBlocks $ClassName $.LegacyBlocks) .Properties}} - {{- if ne (len $NewProperties) 0 }} planned{{ .ResourceClassName }} := {{ .ResourceClassName }}{{$.ResourceClassName}}ResourceModel{} foundAttributeValue := false for _, newAttributeValue := range newAttributeValues { - {{- range .Properties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if and (ne $AttributeName "") (.IsRequired) (or (eq .Name "TDn") (isNewNamedClassAttribute $Overwrite)) }} + {{- range .Properties}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} + {{- if and (ne $AttributeName "") (.IsRequired) (or (eq .Name "TDn") (isNewNamedClassAttribute $Overwrite)) }} if newAttributeValue.{{ .Name }}.ValueString() == {{- if isNewNamedClassAttribute $Overwrite }}GetMOName(attributeValue.{{ $AttributeName }}.ValueString()){{- else}}attributeValue.TDn.ValueString(){{- end}} { planned{{ .ResourceClassName }} = newAttributeValue - {{- if ne (len $NewProperties) 0 }} foundAttributeValue = true - {{- end}} break } } + {{- end}} {{- end}} - {{- end}} - {{- end}} - - {{- range .Properties}} + {{- range .Properties}} {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} {{- if or (eq .Name "TDn") (isNewNamedClassAttribute $Overwrite)}} {{ .Name | decapitalize }}Value := basetypes.NewStringUnknown() if !attributeValue.{{ $AttributeName }}.IsUnknown() { - {{ .Name | decapitalize }}Value = {{- if isNewNamedClassAttribute $Overwrite }}basetypes.NewStringValue(GetMOName(attributeValue.{{ $AttributeName }}.ValueString())){{- else}}basetypes.NewStringValue(attributeValue.TDn.ValueString()){{- end}} + {{ .Name | decapitalize }}Value = {{ if isNewNamedClassAttribute $Overwrite }}basetypes.NewStringValue(GetMOName(attributeValue.{{ $AttributeName }}.ValueString())){{- else}}basetypes.NewStringValue(attributeValue.TDn.ValueString()){{- end}} } {{- end}} - {{- end}} - + {{- end}} {{ .ResourceClassName }} := {{ .ResourceClassName }}{{$.ResourceClassName}}ResourceModel { {{- range .Properties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if or (eq .Name "TDn") (isNewNamedClassAttribute $Overwrite) (eq .Name "Annotation")}} + {{- if or .IsRequired (eq .Name "Annotation")}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} + {{- if or (eq .Name "TDn") (isNewNamedClassAttribute $Overwrite) }} {{ .Name }}: {{ .Name | decapitalize }}Value, - {{- else if and (ne $AttributeName "") (not (isNewNamedClassAttribute $Overwrite)) }} - {{- if .HasCustomType}} + {{ else if eq .Name "Annotation"}} + {{ .Name }}: planData.{{ .Name }}, + {{- else if and (ne $AttributeName "") (not (isNewNamedClassAttribute $Overwrite)) }} + {{- if .HasCustomType}} {{ .Name }}: customTypes.{{.ResourceClassName}}{{.Name}}StringValue{StringValue: attributeValue.{{ .Name }}}, - {{- else}} + {{- else}} {{ .Name }}: attributeValue.{{ .Name }}, + {{- end}} {{- end}} {{- end}} {{- end}} } - - {{- if ne (len $NewProperties) 0}} - - if foundAttributeValue { - {{- range $NewProperties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{ .ResourceClassName }}.{{ .Name }} = planned{{ .ResourceClassName }}.{{ .Name }} - {{- end}} - } else { - {{- range $NewProperties}} - {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} - {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} - {{- if isNewNamedClassAttribute $Overwrite }} - {{ .ResourceClassName }}.{{ .Name }} = {{ .Name | decapitalize }}Value - {{- else if ne .DefaultValue ""}} - {{ .ResourceClassName }}.{{ .Name }} = basetypes.NewStringValue("{{.DefaultValue}}") // Default to default value from meta when not found - {{- else}} + {{- range .Properties}} + {{- if and (not .IsRequired) (ne .Name "Annotation")}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} + if !attributeValue.{{ .Name }}.IsNull() { + {{- if .HasCustomType}} + {{ .ResourceClassName }}.{{ .Name }} = customTypes.{{.ResourceClassName}}{{.Name}}StringValue{StringValue: attributeValue.{{ .Name }}} + {{- else}} {{ .ResourceClassName }}.{{ .Name }} = attributeValue.{{ .Name }} + {{- end}} + } else { + {{- if .HasCustomType}} + {{ .ResourceClassName }}.{{ .Name }} = customTypes.{{.ResourceClassName}}{{.Name}}StringValue{StringValue: basetypes.NewStringUnknown()} + {{- else}} + {{ .ResourceClassName }}.{{ .Name }} = basetypes.NewStringUnknown() + {{- end}} + } {{- end}} {{- end}} + if foundAttributeValue { + {{- range $NewProperties}} + {{- $Overwrite := overwriteProperty .PkgName .SnakeCaseName $.Definitions}} + {{- $AttributeName := getLegacyChildAttribute .PkgName $Overwrite . $.LegacyAttributes $.LegacyBlocks}} + {{ .ResourceClassName }}.{{ .Name }} = planned{{ .ResourceClassName }}.{{ .Name }} + {{- end}} + {{- range .Properties}} + {{- if eq .Name "Annotation"}} + {{ .ResourceClassName }}.{{ .Name }} = planned{{ .ResourceClassName }}.{{ .Name }} + {{- end}} + {{- end}} } - {{- end}} - {{- $resourceClassName:= .ResourceClassName}} - {{- range .Children}} - {{- if or (not .IdentifiedBy) .MaxOneClassAllowed}} + {{- $resourceClassName:= .ResourceClassName}} + {{- range .Children}} + {{- if or (not .IdentifiedBy) .MaxOneClassAllowed}} {{ .ResourceClassName | decapitalize }}{{.ParentHierarchy}}Value, _ := types.ObjectValueFrom(ctx, {{ .ResourceClassName }}{{.ParentHierarchy}}Type, getEmpty{{ .ResourceClassName }}{{.ParentHierarchy}}ResourceModel()) - {{- else}} + {{- else}} {{ .ResourceClassName | decapitalize }}{{.ParentHierarchy}}Value, _ := types.SetValueFrom(ctx, {{ .ResourceClassName }}{{.ParentHierarchy}}Type, make([]{{ .ResourceClassName }}{{.ParentHierarchy}}ResourceModel, 0)) - {{- end}} + {{- end}} {{ $resourceClassName }}.{{.ResourceClassName}} = {{ .ResourceClassName | decapitalize }}{{.ParentHierarchy}}Value - {{- end}} + {{- end}} {{.ResourceClassName}}List = append({{.ResourceClassName}}List, {{ .ResourceClassName }}) } - {{.ResourceClassName}}Set, _ := types.SetValueFrom(ctx, {{.ResourceClassName}}{{.ParentHierarchy}}Type, {{.ResourceClassName}}List) planData.{{.ResourceClassName}} = {{.ResourceClassName}}Set - - {{- end }} + } else if !configData.{{.ResourceClassName}}.IsNull() && stateData == nil { + setUnknownDeprecated{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModelToPlan(ctx , planData) + } {{- end }} {{- end }} - } + {{- end }} {{ end }} {{ end }} + {{- if .LegacyAttributes}} + + // Workaround to compare the state with plan to avoid plan changes with only known after apply + if stateData != nil { + avoid{{.ResourceClassName}}PlanChangeForKnownAfterApplyOnly(ctx, planData, stateData, configData) + } + {{- end}} + resp.Diagnostics.Append(resp.Plan.Set(ctx, &planData)...) } } + +{{- if .LegacyAttributes}} + + {{- if .LegacyBlocks}} + {{- range .LegacyBlocks}} +func setUnknownDeprecated{{capitalize .ClassName}}{{$.ResourceClassName}}ResourceModelToPlan(ctx context.Context, planData *{{$.ResourceClassName}}ResourceModel) { + var attributeValues []{{capitalize .ClassName}}{{$.ResourceClassName}}ResourceModel + var legacyAttributeValues []{{capitalize .ClassName}}{{$.ResourceClassName}}ResourceModelV1 + planData.{{capitalize .ClassName}}.ElementsAs(ctx, &attributeValues, false) + for i := 0; i < len(attributeValues); i++ { + legacyAttributeValues = append(legacyAttributeValues, {{capitalize .ClassName}}{{$.ResourceClassName}}ResourceModelV1{ {{- range .Attributes}} + {{.Name}}: basetypes.NewStringUnknown(), + {{- end}} + }) + } + Deprecated{{capitalize .ClassName}}Set, _ := types.SetValueFrom(ctx, deprecated{{capitalize .ClassName}}Type, legacyAttributeValues) + planData.Deprecated{{capitalize .ClassName}} = Deprecated{{capitalize .ClassName}}Set +} + {{- end}} + {{- end}} + +func avoid{{.ResourceClassName}}PlanChangeForKnownAfterApplyOnly(ctx context.Context, planData, stateData, configData *{{.ResourceClassName}}ResourceModel) { + // Set read-only and deprecated attributes in planData from stateData + {{- range .Properties}} + {{- if .ReadOnly}} + planData.{{.Name}} = stateData.{{.Name}} + {{- end}} + {{- end}} + {{- range .LegacyAttributes}} + {{- if ne .ReplacedBy.AttributeName "" }} + if configData.Deprecated{{ .Name }}.IsNull() { + planData.Deprecated{{.Name}} = stateData.Deprecated{{.Name}} + } + {{- end}} + {{- end }} + {{- range .LegacyBlocks}} + if configData.Deprecated{{ capitalize .ClassName }}.IsNull() { + planData.Deprecated{{ capitalize .ClassName }} = stateData.Deprecated{{ capitalize .ClassName }} + } + {{- end }} + + // Compare the string representation of the planData and stateData because structs cannot be compared directly + if fmt.Sprintf("%s", planData) != fmt.Sprintf("%s", stateData) { + {{- range .Properties}} + {{- if .ReadOnly}} + planData.{{.Name}} = basetypes.NewStringUnknown() + {{- end}} + {{- end}} + {{- range .LegacyAttributes}} + {{- if ne .ReplacedBy.AttributeName "" }} + {{- if eq (getMigrationType .ValueType) "String"}} + if configData.Deprecated{{.Name}}.IsNull() { + planData.Deprecated{{.Name}} = basetypes.NewStringUnknown() + } + {{- else if eq (getMigrationType .ValueType) "Set"}} + if configData.Deprecated{{.Name}}.IsNull() { + planData.Deprecated{{.Name}} = basetypes.NewSetUnknown(basetypes.StringType{}) + } + {{- end}} + {{- end}} + {{- end }} + {{- if .LegacyBlocks}} + {{- range .LegacyBlocks}} + if configData.Deprecated{{ capitalize .ClassName }}.IsNull() { + setUnknownDeprecated{{capitalize .ClassName}}{{$.ResourceClassName}}ResourceModelToPlan(ctx, planData) + } + {{- end}} + {{- end}} + } +} +{{- end}} + {{- if .TypeChanges}} {{- range $version, $value := .TypeChanges}} type {{$.ResourceClassName}}ResourceModelV{{$version}} struct { @@ -1421,6 +1446,7 @@ func (r *{{.ResourceClassName}}Resource) Schema(ctx context.Context, req resourc DeprecationMessage: "Attribute `{{.AttributeName}}` is deprecated. The attribute will be removed in the next major version of the provider.", PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, }, {{- end}} @@ -1501,7 +1527,7 @@ func (r *{{.ResourceClassName}}Resource) Schema(ctx context.Context, req resourc {{- if not .ReadOnly }} PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(nil), }, {{- end}} @@ -1522,9 +1548,12 @@ func (r *{{.ResourceClassName}}Resource) Schema(ctx context.Context, req resourc {{- end}} {{- if or .IsNaming .IsRequired}} {{- if ne $LegacyAttributeName ""}} - {{- if not .ReadOnly }} - Optional: true, - {{- end }} + {{- if not .ReadOnly }} + Optional: true, + {{- end }} + Computed: true, + {{else if $.HasReadOnlyProperties}} + Optional: true, Computed: true, {{- else}} Required: true, @@ -1568,6 +1597,10 @@ func (r *{{.ResourceClassName}}Resource) Schema(ctx context.Context, req resourc path.MatchRoot("{{$LegacyAttributeName}}"), }...), {{- end}} + }, + {{- else if and (or .IsNaming .IsRequired) $.HasReadOnlyProperties}} + Validators: []validator.String{ + MakeStringRequired(), }, {{- end}} MarkdownDescription: `{{.Comment}}`, @@ -1595,6 +1628,9 @@ func (r *{{.ResourceClassName}}Resource) Schema(ctx context.Context, req resourc stringvalidator.ConflictsWith(path.Expressions{ path.MatchRoot("{{getConflictingAttributeName .ReplacedBy.AttributeName}}"), }...), + {{- if .Required }} + MakeStringRequired(), + {{- end }} }, }, {{- end}} @@ -2528,6 +2564,7 @@ func getEmpty{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModel() {{.Resour {{- end}} } } + {{- if or (not .IdentifiedBy) .MaxOneClassAllowed}} var {{.ResourceClassName}}{{.ParentHierarchy}}Type = map[string]attr.Type{ {{- range .Properties}} @@ -2566,6 +2603,41 @@ var {{.ResourceClassName}}{{.ParentHierarchy}}Type = types.ObjectType{ {{- end}} }, } + +{{- if excludeForNullInSetCheck .ResourceClassName}} +func {{.ResourceClassName}}{{.ParentHierarchy}}SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + {{- range .Properties}} + if stateValue.{{ .Name }}.IsNull() { + nullInStateFound = true + {{- if eq .ValueType "bitmask"}} + planSetValues[index].{{ .Name }} = basetypes.NewSetNull(types.StringType) + {{- else if .HasCustomType}} + planSetValues[index].{{ .Name }} = customTypes.New{{.ResourceClassName}}{{.Name}}StringNull() + {{- else}} + planSetValues[index].{{ .Name }} = basetypes.NewStringNull() + {{- end}} + } + {{- end}} + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, {{.ResourceClassName}}{{.ParentHierarchy}}Type, planSetValues) + return planSet + +} +{{- end}} {{- end}} {{- range .Children}} {{- template "childStructsAndAttributeTypes" . }} @@ -2643,6 +2715,9 @@ var {{.ResourceClassName}}{{.ParentHierarchy}}Type = types.ObjectType{ Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + {{- if excludeForNullInSetCheck .ResourceClassName}} + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate({{.ResourceClassName}}{{.ParentHierarchy}}SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), + {{- end}} }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ diff --git a/gen/templates/resource_test.go.tmpl b/gen/templates/resource_test.go.tmpl index 20f3f9fff..6a79a532e 100644 --- a/gen/templates/resource_test.go.tmpl +++ b/gen/templates/resource_test.go.tmpl @@ -851,9 +851,30 @@ PreCheck: func() { testAccPreCheck(t, "{{.test_type}}", "{{$.class_version}}") } ), }, {{- end}} + {{- if $.legacy_attributes}} + // Update with legacy attribute config + { + Config: testConfig{{$.resourceClassName}}LegacyAttributesWith{{capitalize .class_name}}{{if $.version_mismatch}} + testConfigDataSourceSystem{{end}}, + ExpectNonEmptyPlan: {{.class_in_parent}}, + }, + {{- end}} + }, + CheckDestroy: testCheckResourceDestroy, + }) + {{- if $.legacy_attributes}} + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t, "apic", "1.0(1e)-") }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create with legacy attribute config + { + Config: testConfig{{$.resourceClassName}}LegacyAttributesWith{{capitalize .class_name}}{{if $.version_mismatch}} + testConfigDataSourceSystem{{end}}, + ExpectNonEmptyPlan: false, + }, }, CheckDestroy: testCheckResourceDestroy, }) + {{- end}} } {{- end}} {{- else}} func TestAccResource{{.resourceClassName}}(t *testing.T) { @@ -1692,7 +1713,11 @@ resource "aci_{{$target.target_resource_name}}" "test_{{$target.target_resource_ {{$target.parent_dn_key}} = {{$target.parent_dependency_dn_ref}} {{- end}} {{- range $key, $value := $target.properties}} + {{- if contains $value "."}} + {{$key}} = {{$value}} + {{- else}} {{$key}} = "{{$value}}" + {{- end}} {{- end}} }{{$testIndex = add $testIndex 1}} @@ -1710,7 +1735,7 @@ resource "aci_{{$.resourceName}}" "allow_test" { {{- end}} {{- range $key, $value := $.resource_required}} {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true $target_classes 0 false}} - {{$key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$key}} = "{{$value}}" {{- end }} @@ -1722,7 +1747,7 @@ resource "aci_{{$.resourceName}}" "allow_test_2" { {{- end}} {{- range $key, $value := $.resource_required}} {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true $target_classes 0 false}} - {{$key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$key}} = "{{$value}}" {{- end }} @@ -1738,7 +1763,7 @@ resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClas {{- end}} {{- range $key, $value := $.resource_required}} {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true $target_classes 0 false}} - {{$key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$key}} = "{{$value}}" {{- end }} @@ -1754,7 +1779,7 @@ resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClas {{- range $key, $value := $.resource_required}}{{$contains := definedInMap $key $.all}} {{- if not $contains}} {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true $target_classes 0 false}} - {{$key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$key}} = "{{$value}}" {{- end }} @@ -1798,7 +1823,7 @@ resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClas {{- range $key, $value := $.resource_required}}{{$contains := definedInMap $key $.default}} {{- if not $contains}} {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true $target_classes 0 false}} - {{$key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$key}} = "{{$value}}" {{- end }} @@ -1842,7 +1867,7 @@ resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClas {{- end}} {{- range $key, $value := $.resource_required}} {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true $target_classes 0 false}} - {{$key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$key}} = "{{$value}}" {{- end }} @@ -1863,15 +1888,15 @@ resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClas {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil $index false}} - {{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else if (isInterfaceSlice $child_value)}} {{- if lt 0 (len $child_value)}} {{$child_key}} = [{{range $index, $subvalue := $child_value}}{{if lt $index (subtract (len $child_value) 1)}}"{{$subvalue}}", {{else}}"{{$subvalue}}"{{end}}{{end}}] {{- else}} {{$child_key}} = [] {{- end}} - {{- else if ne $child_key "deletable_child"}} - {{$child_key}} = "{{$child_value}}" + {{- else if ne $child_key "deletable_child"}}{{$attributeValue := getTestTargetValue $.child_targets $child_key $child_value}} + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- end}} {{- end}} {{- end}}{{ $index = add $index 1 }} @@ -1892,9 +1917,9 @@ resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClas {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil $index false}} - {{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} - {{- else if ne $child_key "deletable_child"}} - {{$child_key}} = "{{$child_value}}" + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{- else if ne $child_key "deletable_child"}}{{$attributeValue := getTestTargetValue $.child_targets $child_key $child_value}} + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- end}} {{- end}} {{- end}}{{ $index = add $index 1 }} @@ -1913,7 +1938,7 @@ resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClas {{- end}} {{- range $key, $value := $.resource_required}} {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true $target_classes 0 false}} - {{$key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$key}} = "{{$value}}" {{- end }} @@ -1928,7 +1953,7 @@ resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClas {{- end}} {{- range $key, $value := $.resource_required}} {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true $target_classes 0 false}} - {{$key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$key}} = "{{$value}}" {{- end }} @@ -1952,15 +1977,15 @@ resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClas {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil $index false}} - {{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else if (isInterfaceSlice $child_value)}} {{- if lt 0 (len $child_value)}} {{$child_key}} = [{{range $index, $subvalue := $child_value}}{{if lt $index (subtract (len $child_value) 1)}}"{{$subvalue}}", {{else}}"{{$subvalue}}"{{end}}{{end}}] {{- else}} {{$child_key}} = [] {{- end}} - {{- else if ne $child_key "deletable_child"}} - {{$child_key}} = "{{$child_value}}" + {{- else if ne $child_key "deletable_child"}}{{$attributeValue := getTestTargetValue $.child_targets $child_key $child_value}} + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- end}} {{- end}} {{- end}}{{ $index = add $index 1 }} @@ -1981,9 +2006,9 @@ resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClas {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil 1 false}} - {{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} - {{- else }} - {{$child_key}} = "{{$child_value}}" + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{- else }}{{$attributeValue := getTestTargetValue $.child_targets $child_key $child_value}} + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- end}} {{- end}} {{- end}} @@ -2001,7 +2026,7 @@ resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClas {{- end}} {{- range $key, $value := $.resource_required}} {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true $target_classes 0 false}} - {{$key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$key}} = "{{$value}}" {{- end }} @@ -2025,15 +2050,15 @@ resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClas {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil $index false}} - {{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else if (isInterfaceSlice $child_value)}} {{- if lt 0 (len $child_value)}} {{$child_key}} = [{{range $index, $subvalue := $child_value}}{{if lt $index (subtract (len $child_value) 1)}}"{{$subvalue}}", {{else}}"{{$subvalue}}"{{end}}{{end}}] {{- else}} {{$child_key}} = [] {{- end}} - {{- else if ne $child_key "deletable_child"}} - {{$child_key}} = "{{$child_value}}" + {{- else if ne $child_key "deletable_child"}}{{$attributeValue := getTestTargetValue $.child_targets $child_key $child_value}} + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- end}} {{- end}} {{- end}}{{ $index = add $index 1 }} @@ -2048,16 +2073,39 @@ resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClas {{- end}} {{if $.custom_type}} -const testConfig{{$.resourceClassName}}CustomTypeDependencyWith{{capitalize .class_name}} = {{- if $dependencies }} testDependencyConfig{{$.resourceClassName}} + {{- end }} testConfig{{capitalize .class_name}}Min{{- if ne .parent_dependency ""}}DependencyWith{{capitalize .parent_dependency}}{{if and (ne .parent_dependency_name nil) (ne .parent_dependency_name "")}}{{capitalize .parent_dependency_name }}{{- end }}{{- end}} + ` +const testConfig{{$.resourceClassName}}CustomTypeDependencyWith{{capitalize .class_name}} = {{- if $dependencies }} testDependencyConfig{{$.resourceClassName}} + {{- end }}{{- if $childDependencies }} testChildDependencyConfig{{$.resourceClassName}} + {{- end }} {{if .class_name}}testConfig{{capitalize .class_name}}Min{{- if ne .parent_dependency ""}}DependencyWith{{capitalize .parent_dependency}}{{if and (ne .parent_dependency_name nil) (ne .parent_dependency_name "")}}{{capitalize .parent_dependency_name }}{{- end }}{{- end}} + {{- end}} ` resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClassName }}_1{{- end }}" { parent_dn = {{.parent_dn}} - {{- range $key, $value := $.custom_type}} - {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true $target_classes 0 false}} - {{$key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} - {{- else }} + {{- range $key, $value := $.custom_type}} + {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true $target_classes 0 false}} + {{$key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{- else }} {{$key}} = "{{$value}}" - {{- end }} - {{- end}} + {{- end }} + {{- end}} +} +` + {{- end}} + {{- if $.legacy_attributes }} +const testConfig{{$.resourceClassName}}LegacyAttributesWith{{capitalize .class_name}} = {{- if $dependencies }} testDependencyConfig{{$.resourceClassName}} + {{- end }}{{- if $childDependencies }} testChildDependencyConfig{{$.resourceClassName}} + {{- end }} {{if .class_name}}testConfig{{capitalize .class_name}}Min{{- if ne .parent_dependency ""}}DependencyWith{{capitalize .parent_dependency}}{{if and (ne .parent_dependency_name nil) (ne .parent_dependency_name "")}}{{capitalize .parent_dependency_name }}{{- end }}{{- end}} + {{- end}} ` +resource "aci_{{$.resourceName}}" "test{{- if eq $.resourceClassName $parentClassName }}_1{{- end }}" { + {{- range $key, $value := $.resource_required}} + {{$key}} = "{{$value}}" + {{- end}} + {{- range $key, $value := $.legacy_attributes}} + {{- if isInterfaceSlice $value}}{{$list_value := index $value 0}} + {{$key}} = {{if isReference $list_value}}{{$value}}{{else}}["{{$list_value}}"]{{end}} + {{- else}} + {{$key}} = {{if isReference $value}}{{$value}}{{else}}"{{$value}}"{{end}} + {{- end}} + {{- end}} + {{- range $key, $value := $.legacy_blocks}} + {{$key}} { + {{- range $block_key, $block_value := $value}} + {{$block_key}} = {{if isReference $block_value}}{{$block_value}}{{else}}"{{$block_value}}"{{end}} + {{- end}} + } + {{- end}} } ` {{- end}} @@ -2165,7 +2213,7 @@ const testConfig{{.resourceClassName}}Children = {{- if $childDependencies }} te resource "aci_{{$.resourceName}}" "test" { {{- range $key, $value := $.resource_required}} {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true nil 0 false}} - {{$key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$key}} = "{{$value}}" {{- end }} @@ -2194,7 +2242,7 @@ resource "aci_{{$.resourceName}}" "test" { {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil $index false}} - {{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else if (isInterfaceSlice $child_value)}} {{- if lt 0 (len $child_value)}} {{$child_key}} = [{{range $index, $subvalue := $child_value}}{{if lt $index (subtract (len $child_value) 1)}}"{{$subvalue}}", {{else}}"{{$subvalue}}"{{end}}{{end}}] @@ -2223,7 +2271,7 @@ resource "aci_{{$.resourceName}}" "test" { {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil $index false}} - {{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else if ne $child_key "deletable_child"}} {{$child_key}} = "{{$child_value}}" {{- end}} @@ -2248,7 +2296,7 @@ const testConfig{{.resourceClassName}}ChildrenRemoveFromConfig = {{- if $childDe resource "aci_{{$.resourceName}}" "test" { {{- range $key, $value := $.resource_required}} {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true nil 0 false}} - {{$key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$key}} = "{{$value}}" {{- end }} @@ -2260,7 +2308,7 @@ const testConfig{{.resourceClassName}}ChildrenRemoveOne = {{- if $childDependenc resource "aci_{{$.resourceName}}" "test" { {{- range $key, $value := $.resource_required}} {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true nil 0 false}} - {{$key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$key}} = "{{$value}}" {{- end }} @@ -2292,7 +2340,7 @@ resource "aci_{{$.resourceName}}" "test" { {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil $index false}} - {{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else if (isInterfaceSlice $child_value)}} {{- if lt 0 (len $child_value)}} {{$child_key}} = [{{range $index, $subvalue := $child_value}}{{if lt $index (subtract (len $child_value) 1)}}"{{$subvalue}}", {{else}}"{{$subvalue}}"{{end}}{{end}}] @@ -2321,7 +2369,7 @@ resource "aci_{{$.resourceName}}" "test" { {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil 1 false}} - {{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$child_key}} = "{{$child_value}}" {{- end}} @@ -2338,7 +2386,7 @@ const testConfig{{.resourceClassName}}ChildrenRemoveAll = {{- if $childDependenc resource "aci_{{$.resourceName}}" "test" { {{- range $key, $value := $.resource_required}} {{- if eq $key "target_dn" }}{{$attributeValue := getTestTargetDn $.targets $.resourceName $value true nil 0 false}} - {{$key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$key}} = "{{$value}}" {{- end }} @@ -2370,7 +2418,7 @@ resource "aci_{{$.resourceName}}" "test" { {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil $index false}} - {{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else if (isInterfaceSlice $child_value)}} {{- if lt 0 (len $child_value)}} {{$child_key}} = [{{range $index, $subvalue := $child_value}}{{if lt $index (subtract (len $child_value) 1)}}"{{$subvalue}}", {{else}}"{{$subvalue}}"{{end}}{{end}}] @@ -2432,7 +2480,7 @@ resource "aci_{{$.resourceName}}" "test" { {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil $index false}} - {{$indent}}{{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$indent}}{{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else if (isInterfaceSlice $child_value)}} {{- if lt 0 (len $child_value)}} {{$indent}}{{$child_key}} = [{{range $index, $subvalue := $child_value}}{{if lt $index (subtract (len $child_value) 1)}}"{{$subvalue}}", {{else}}"{{$subvalue}}"{{end}}{{end}}] @@ -2461,7 +2509,7 @@ resource "aci_{{$.resourceName}}" "test" { {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil $index false}} - {{$indent}}{{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$indent}}{{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else if ne $child_key "deletable_child"}} {{$indent}}{{$child_key}} = "{{$child_value}}" {{- end}} @@ -2505,7 +2553,7 @@ resource "aci_{{$.resourceName}}" "test" { {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil $index false}} - {{$indent}}{{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$indent}}{{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else if (isInterfaceSlice $child_value)}} {{- if lt 0 (len $child_value)}} {{$indent}}{{$child_key}} = [{{range $index, $subvalue := $child_value}}{{if lt $index (subtract (len $child_value) 1)}}"{{$subvalue}}", {{else}}"{{$subvalue}}"{{end}}{{end}}] @@ -2534,7 +2582,7 @@ resource "aci_{{$.resourceName}}" "test" { {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil 1 false}} - {{$indent}}{{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$indent}}{{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else }} {{$indent}}{{$child_key}} = "{{$child_value}}" {{- end}} @@ -2576,15 +2624,15 @@ resource "aci_{{$.resourceName}}" "test" { {{- end }} {{- else }} {{- if eq $child_key "target_dn"}}{{$attributeValue := getTestTargetDn $.child_targets $key $child_value true nil $index false}} - {{$indent}}{{$child_key}} = {{if containsString $attributeValue "."}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} + {{$indent}}{{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- else if (isInterfaceSlice $child_value)}} {{- if lt 0 (len $child_value)}} {{$indent}}{{$child_key}} = [{{range $index, $subvalue := $child_value}}{{if lt $index (subtract (len $child_value) 1)}}"{{$subvalue}}", {{else}}"{{$subvalue}}"{{end}}{{end}}] {{- else}} {{$indent}}{{$child_key}} = [] {{- end}} - {{- else if ne $child_key "deletable_child"}} - {{$indent}}{{$child_key}} = "{{$child_value}}" + {{- else if ne $child_key "deletable_child"}}{{$attributeValue := getTestTargetValue $.child_targets $child_key $child_value}} + {{$indent}}{{$child_key}} = {{if isReference $attributeValue}}{{$attributeValue}}{{else}}"{{$attributeValue}}"{{end}} {{- end}} {{- end}} {{- end}}{{ $index = add $index 1 }} diff --git a/gen/templates/testvars.yaml.tmpl b/gen/templates/testvars.yaml.tmpl index 3edbccc20..7154ac6c4 100644 --- a/gen/templates/testvars.yaml.tmpl +++ b/gen/templates/testvars.yaml.tmpl @@ -2,6 +2,34 @@ # In order to regenerate this file execute `go generate` from the repository root. # More details can be found in the [README](https://github.com/CiscoDevNet/terraform-provider-aci/blob/master/README.md). +{{- if .LegacyAttributes}} +legacy_attributes: + {{- range .LegacyAttributes}} + {{- if ne .ReplacedBy.AttributeName "" }} + {{- if eq (getMigrationType .ValueType) "String"}} + {{.AttributeName}}: "{{getLegacyPropertyTestValue .Name $}}" + {{- else if eq (getMigrationType .ValueType) "Set"}} + {{.AttributeName}}: ["{{getLegacyPropertyTestValue .Name $}}"] + {{- end}} + {{- end}} + {{- end }} +{{- end}} +{{- if .LegacyBlocks}} +legacy_blocks: + {{- range .LegacyBlocks}}{{$ClassName := .ClassName}} + {{.Name }}: + {{- range .Attributes}} + {{- if ne .ReplacedBy.AttributeName "" }} + {{- if eq (getMigrationType .ValueType) "String"}} + {{.AttributeName}}: "{{getLegacyBlockTestValue $ClassName .Name $}}" + {{- else if eq (getMigrationType .ValueType) "Set"}} + {{.AttributeName}}: ["{{getLegacyBlockTestValue $ClassName .Name $}}"] + {{- end}} + {{- end}} + {{- end }} + {{- end}} +{{ end}} + {{ $versionMismatch := .VersionMismatched}} default: {{- $versionMismatchExists := false}} diff --git a/gen/testvars/fvAEPg.yaml b/gen/testvars/fvAEPg.yaml index a048261aa..da09e67bb 100644 --- a/gen/testvars/fvAEPg.yaml +++ b/gen/testvars/fvAEPg.yaml @@ -1,6 +1,38 @@ # Code generated by "gen/generator.go"; DO NOT EDIT. # In order to regenerate this file execute `go generate` from the repository root. # More details can be found in the [README](https://github.com/CiscoDevNet/terraform-provider-aci/blob/master/README.md). +legacy_attributes: + exception_tag: "contract_exception_tag_1" + flood_on_encap: "disabled" + fwd_ctrl: "none" + has_mcast_source: "no" + is_attr_based_epg: "no" + match_t: "All" + application_profile_dn: "aci_application_profile.test.id" + pc_enf_pref: "enforced" + pref_gr_memb: "exclude" + prio: "level1" + shutdown: "no" + relation_fv_rs_aepg_mon_pol: "aci_monitoring_policy.test_monitoring_policy_0.id" + relation_fv_rs_bd: "aci_bridge_domain.test_bridge_domain_1.id" + relation_fv_rs_cons: ["aci_contract.test_contract_1.id"] + relation_fv_rs_sec_inherited: ["aci_application_epg.test_application_epg_0.id"] + relation_fv_rs_cust_qos_pol: "aci_custom_qos_policy.test_custom_qos_policy_0.id" + relation_fv_rs_dpp_pol: "aci_data_plane_policing_policy.test_data_plane_policing_policy_1.id" + relation_fv_rs_fc_path_att: ["topology/pod-1/paths-101/pathep-[eth1/1]"] + relation_fv_rs_cons_if: ["aci_imported_contract.test_imported_contract_1.id"] + relation_fv_rs_intra_epg: ["aci_contract.test_contract_1.id"] + relation_fv_rs_prov: ["aci_contract.test_contract_1.id"] + relation_fv_rs_prot_by: ["aci_taboo_contract.test_taboo_contract_1.id"] + relation_fv_rs_trust_ctrl: "aci_trust_control_policy.test_trust_control_policy_0.id" +legacy_blocks: + relation_fv_rs_node_att: + deployment_immediacy: "immediate" + description: "description_1" + encap: "vlan-101" + mode: "native" + node_dn: "topology/pod-1/node-101" + default: @@ -649,6 +681,83 @@ parents: class_in_parent: false test_type: apic child_targets: + - class_name: "monEPGPol" + target_dn: "uni/tn-test_tenant/monepg-monitoring_policy_name_1" + relation_resource_name: "monitoring_policy" + static: false + target_dn_ref: "aci_monitoring_policy.test_monitoring_policy_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "monitoring_policy" + parent_dn_key: "tenant_dn" + properties: + name: "monitoring_policy_name_1" + - class_name: "fvBD" + target_dn: "uni/tn-test_tenant/BD-bridge_domain_name_1" + relation_resource_name: "bridge_domain_name" + static: false + target_dn_ref: "aci_bridge_domain.test_bridge_domain_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "bridge_domain" + parent_dn_key: "parent_dn" + properties: + name: "bridge_domain_name_1" + - class_name: "vzBrCP" + target_dn: "uni/tn-test_tenant/brc-contract_name_0" + relation_resource_name: "contract" + static: false + target_dn_ref: "aci_contract.test_contract_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "contract" + parent_dn_key: "tenant_dn" + properties: + name: "contract_name_0" + - class_name: "vzBrCP" + target_dn: "uni/tn-test_tenant/brc-contract_name_1" + relation_resource_name: "contract" + static: false + target_dn_ref: "aci_contract.test_contract_1.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "contract" + parent_dn_key: "tenant_dn" + properties: + name: "contract_name_1" + - class_name: "vzCPIf" + target_dn: "uni/tn-test_tenant/cif-imported_contract_name_0" + relation_resource_name: "imported_contract" + static: false + target_dn_ref: "aci_imported_contract.test_imported_contract_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "imported_contract" + parent_dn_key: "tenant_dn" + properties: + name: "imported_contract_name_0" + - class_name: "vzCPIf" + target_dn: "uni/tn-test_tenant/cif-imported_contract_name_1" + relation_resource_name: "imported_contract" + static: false + target_dn_ref: "aci_imported_contract.test_imported_contract_1.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "imported_contract" + parent_dn_key: "tenant_dn" + properties: + name: "imported_contract_name_1" + - class_name: "qosCustomPol" + target_dn: "uni/tn-test_tenant/qoscustom-custom_qos_policy_name_1" + relation_resource_name: "custom_qos_policy" + static: false + target_dn_ref: "aci_custom_qos_policy.test_custom_qos_policy_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "custom_qos_policy" + parent_dn_key: "parent_dn" + properties: + name: "custom_qos_policy_name_1" - class_name: "vmmDomP" target_dn: "uni/vmmp-VMware/dom-domain_1" relation_resource_name: "domain" @@ -657,6 +766,17 @@ child_targets: target_dn: "uni/vmmp-VMware/dom-domain_2" relation_resource_name: "domain" static: true + - class_name: "qosDppPol" + target_dn: "uni/tn-test_tenant/qosdpppol-data_plane_policing_policy_name_1" + relation_resource_name: "data_plane_policing_policy" + static: false + target_dn_ref: "aci_data_plane_policing_policy.test_data_plane_policing_policy_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "data_plane_policing_policy" + parent_dn_key: "parent_dn" + properties: + name: "data_plane_policing_policy_name_1" - class_name: "fabricPathEp" target_dn: "topology/pod-1/paths-101/pathep-[eth1/1]" relation_resource_name: "fibre_channel_path" @@ -681,8 +801,30 @@ child_targets: target_dn: "topology/pod-1/paths-101/pathep-[eth1/2]" relation_resource_name: "static_path" static: true + - class_name: "vzTaboo" + target_dn: "uni/tn-test_tenant/taboo-taboo_contract_name_0" + relation_resource_name: "taboo_contract" + static: false + target_dn_ref: "aci_taboo_contract.test_taboo_contract_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "taboo_contract" + parent_dn_key: "tenant_dn" + properties: + name: "taboo_contract_name_0" + - class_name: "vzTaboo" + target_dn: "uni/tn-test_tenant/taboo-taboo_contract_name_1" + relation_resource_name: "taboo_contract" + static: false + target_dn_ref: "aci_taboo_contract.test_taboo_contract_1.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "taboo_contract" + parent_dn_key: "tenant_dn" + properties: + name: "taboo_contract_name_1" - class_name: "fvAEPg" - target_dn: "uni/tn-test_tenant/ap-test_ap/epg-epg_2" + target_dn: "uni/tn-test_tenant/ap-test_ap/epg-epg_0" relation_resource_name: "contract_master" static: false target_dn_ref: "aci_application_epg.test_application_epg_0.id" @@ -691,9 +833,9 @@ child_targets: target_resource_name: "application_epg" parent_dn_key: "application_profile_dn" properties: - name: "epg_2" + name: "epg_0" - class_name: "fvAEPg" - target_dn: "uni/tn-test_tenant/ap-test_ap/epg-epg_3" + target_dn: "uni/tn-test_tenant/ap-test_ap/epg-epg_1" relation_resource_name: "contract_master" static: false target_dn_ref: "aci_application_epg.test_application_epg_1.id" @@ -702,6 +844,17 @@ child_targets: target_resource_name: "application_epg" parent_dn_key: "application_profile_dn" properties: - name: "epg_3" + name: "epg_1" + - class_name: "fhsTrustCtrlPol" + target_dn: "uni/tn-test_tenant/trustctrlpol-trust_control_policy_name_1" + relation_resource_name: "trust_control_policy" + static: false + target_dn_ref: "aci_trust_control_policy.test_trust_control_policy_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "trust_control_policy" + parent_dn_key: "parent_dn" + properties: + name: "trust_control_policy_name_1" class_version: 1.0(1e)- version_mismatch: true diff --git a/gen/testvars/fvBD.yaml b/gen/testvars/fvBD.yaml index 125831f00..f9075881a 100644 --- a/gen/testvars/fvBD.yaml +++ b/gen/testvars/fvBD.yaml @@ -1,6 +1,37 @@ # Code generated by "gen/generator.go"; DO NOT EDIT. # In order to regenerate this file execute `go generate` from the repository root. # More details can be found in the [README](https://github.com/CiscoDevNet/terraform-provider-aci/blob/master/README.md). +legacy_attributes: + arp_flood: "no" + ep_clear: "no" + ep_move_detect_mode: "garp" + host_based_routing: "no" + intersite_bum_traffic_allow: "no" + ipv6_mcast_allow: "no" + ll_addr: "fe80::1" + mac: "00:22:BD:F8:19:FE" + mcast_allow: "no" + multi_dst_pkt_act: "bd-flood" + tenant_dn: "aci_tenant.test.id" + unicast_route: "yes" + unk_mac_ucast_act: "flood" + unk_mcast_act: "flood" + v6unk_mcast_act: "flood" + vmac: "00:22:BD:F8:19:FB" + relation_fv_rs_bd_to_relay_p: "aci_dhcp_relay_policy.test_dhcp_relay_policy_0.id" + relation_fv_rs_bd_to_ep_ret: "aci_end_point_retention_policy.test_end_point_retention_policy_1.id" + relation_fv_rs_bd_to_fhs: "aci_first_hop_security_policy.test_first_hop_security_policy_1.id" + relation_fv_rs_igmpsn: "aci_igmp_snooping_policy.test_igmp_snooping_policy_0.id" + relation_fv_rs_bd_to_out: ["aci_l3_outside.test_l3_outside_1.id"] + relation_fv_rs_mldsn: "aci_mld_snooping_policy.test_mld_snooping_policy_1.id" + relation_fv_rs_abd_pol_mon_pol: "aci_monitoring_policy.test_monitoring_policy_0.id" + relation_fv_rs_bd_to_nd_p: "aci_neighbor_discovery_interface_policy.test_neighbor_discovery_interface_policy_0.id" + relation_fv_rs_ctx: "aci_vrf.test_vrf_0.id" +legacy_blocks: + relation_fv_rs_bd_to_netflow_monitor_pol: + flt_type: "ce" + tn_netflow_monitor_pol_name: "aci_netflow_monitor_policy.test_netflow_monitor_policy_1.id" + default: @@ -429,5 +460,140 @@ parents: parent_dn: "aci_tenant.test.id" class_in_parent: false test_type: apic +child_targets: + - class_name: "monEPGPol" + target_dn: "uni/tn-test_tenant/monepg-monitoring_policy_name_1" + relation_resource_name: "monitoring_policy" + static: false + target_dn_ref: "aci_monitoring_policy.test_monitoring_policy_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "monitoring_policy" + parent_dn_key: "tenant_dn" + properties: + name: "monitoring_policy_name_1" + - class_name: "fhsBDPol" + target_dn: "uni/tn-test_tenant/bdpol-first_hop_security_policy_name_1" + relation_resource_name: "first_hop_security_policy" + static: false + target_dn_ref: "aci_first_hop_security_policy.test_first_hop_security_policy_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "first_hop_security_policy" + parent_dn_key: "parent_dn" + properties: + name: "first_hop_security_policy_name_1" + - class_name: "ndIfPol" + target_dn: "uni/tn-test_tenant/ndifpol-neighbor_discovery_interface_policy_name_1" + relation_resource_name: "neighbor_discovery_interface_policy" + static: false + target_dn_ref: "aci_neighbor_discovery_interface_policy.test_neighbor_discovery_interface_policy_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "neighbor_discovery_interface_policy" + parent_dn_key: "parent_dn" + properties: + name: "neighbor_discovery_interface_policy_name_1" + - class_name: "netflowMonitorPol" + target_dn: "uni/tn-test_tenant/monitorpol-netflow_monitor_policy_name_1" + relation_resource_name: "netflow_monitor_policy_name" + static: false + target_dn_ref: "aci_netflow_monitor_policy.test_netflow_monitor_policy_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "netflow_monitor_policy" + parent_dn_key: "parent_dn" + properties: + name: "netflow_monitor_policy_name_1" + - class_name: "fvCtx" + target_dn: "uni/tn-test_tenant/ctx-vrf_name_1" + relation_resource_name: "vrf" + static: false + target_dn_ref: "aci_vrf.test_vrf_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "vrf" + parent_dn_key: "tenant_dn" + properties: + name: "vrf_name_1" + - class_name: "l3extOut" + target_dn: "uni/tn-test_tenant/out-abr_l3_outside_name_1" + relation_resource_name: "l3_outside" + static: false + target_dn_ref: "aci_l3_outside.test_l3_outside_1.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "l3_outside" + parent_dn_key: "tenant_dn" + properties: + name: "l3_outside_name_1" + relation_l3ext_rs_ectx: "aci_vrf.test_vrf_0.id" + - class_name: "l3extOut" + target_dn: "uni/tn-test_tenant/out-abr_l3_outside_name_0" + relation_resource_name: "l3_outside" + static: false + target_dn_ref: "aci_l3_outside.test_l3_outside_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "l3_outside" + parent_dn_key: "tenant_dn" + properties: + name: "l3_outside_name_0" + relation_l3ext_rs_ectx: "aci_vrf.test_vrf_0.id" + - class_name: "rtctrlProfile" + target_dn: "uni/tn-test_tenant/out-abr_l3_outside_name_0/prof-route_control_profile_name_1" + relation_resource_name: "route_control_profile" + static: false + target_dn_ref: "aci_route_control_profile.test_route_control_profile_1.id" + parent_dependency: "l3extOut" + parent_dependency_dn_ref: "aci_l3_outside.test_l3_outside_0.id" + target_resource_name: "route_control_profile" + parent_dn_key: "parent_dn" + properties: + name: "route_control_profile_name_1" + - class_name: "dhcpRelayP" + target_dn: "uni/tn-test_tenant/relayp-dhcp_relay_policy_name_1" + relation_resource_name: "dhcp_relay_policy" + static: false + target_dn_ref: "aci_dhcp_relay_policy.test_dhcp_relay_policy_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "dhcp_relay_policy" + parent_dn_key: "tenant_dn" + properties: + name: "dhcp_relay_policy_name_1" + - class_name: "fvEpRetPol" + target_dn: "uni/tn-test_tenant/epRPol-end_point_retention_policy_name_1" + relation_resource_name: "end_point_retention_policy" + static: false + target_dn_ref: "aci_end_point_retention_policy.test_end_point_retention_policy_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "end_point_retention_policy" + parent_dn_key: "tenant_dn" + properties: + name: "end_point_retention_policy_name_1" + - class_name: "igmpSnoopPol" + target_dn: "uni/tn-test_tenant/snPol-igmp_snooping_policy_name_1" + relation_resource_name: "igmp_snooping_policy" + static: false + target_dn_ref: "aci_igmp_snooping_policy.test_igmp_snooping_policy_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "igmp_snooping_policy" + parent_dn_key: "parent_dn" + properties: + name: "igmp_snooping_policy_name_1" + - class_name: "mldSnoopPol" + target_dn: "uni/tn-test_tenant/mldsnoopPol-mld_snooping_policy_name_1" + relation_resource_name: "mld_snooping_policy" + static: false + target_dn_ref: "aci_mld_snooping_policy.test_mld_snooping_policy_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "mld_snooping_policy" + parent_dn_key: "parent_dn" + properties: + name: "mld_snooping_policy_name_1" class_version: 1.0(1e)- version_mismatch: true diff --git a/gen/testvars/fvESg.yaml b/gen/testvars/fvESg.yaml index 6307cd0c2..5ab2487f5 100644 --- a/gen/testvars/fvESg.yaml +++ b/gen/testvars/fvESg.yaml @@ -1,6 +1,26 @@ # Code generated by "gen/generator.go"; DO NOT EDIT. # In order to regenerate this file execute `go generate` from the repository root. # More details can be found in the [README](https://github.com/CiscoDevNet/terraform-provider-aci/blob/master/README.md). +legacy_attributes: + match_t: "All" + application_profile_dn: "aci_application_profile.test.id" + pc_enf_pref: "enforced" + pref_gr_memb: "exclude" + relation_fv_rs_sec_inherited: ["aci_endpoint_security_group.test_endpoint_security_group_0.id"] + relation_fv_rs_intra_epg: ["aci_contract.test_contract_1.id"] + relation_fv_rs_scope: "aci_vrf.test_vrf_0.id" +legacy_blocks: + relation_fv_rs_cons: + target_dn: "aci_contract.test_contract_0.id" + prio: "level1" + relation_fv_rs_cons_if: + target_dn: "aci_imported_contract.test_imported_contract_0.id" + prio: "level1" + relation_fv_rs_prov: + target_dn: "aci_contract.test_contract_0.id" + match_t: "All" + prio: "level1" + default: @@ -275,6 +295,72 @@ parents: class_in_parent: false test_type: apic child_targets: + - class_name: "vzBrCP" + target_dn: "uni/tn-test_tenant/brc-contract_name_0" + relation_resource_name: "contract" + static: false + target_dn_ref: "aci_contract.test_contract_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "contract" + parent_dn_key: "tenant_dn" + properties: + name: "contract_name_0" + - class_name: "vzBrCP" + target_dn: "uni/tn-test_tenant/brc-contract_name_1" + relation_resource_name: "contract" + static: false + target_dn_ref: "aci_contract.test_contract_1.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "contract" + parent_dn_key: "tenant_dn" + properties: + name: "contract_name_1" + - class_name: "vzCPIf" + target_dn: "uni/tn-test_tenant/cif-imported_contract_name_0" + relation_resource_name: "imported_contract" + static: false + target_dn_ref: "aci_imported_contract.test_imported_contract_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "imported_contract" + parent_dn_key: "tenant_dn" + properties: + name: "imported_contract_name_0" + - class_name: "vzCPIf" + target_dn: "uni/tn-test_tenant/cif-imported_contract_name_1" + relation_resource_name: "imported_contract" + static: false + target_dn_ref: "aci_imported_contract.test_imported_contract_1.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "imported_contract" + parent_dn_key: "tenant_dn" + properties: + name: "imported_contract_name_1" + - class_name: "fvCtx" + target_dn: "uni/tn-test_tenant/ctx-vrf_name_1" + relation_resource_name: "vrf" + static: false + target_dn_ref: "aci_vrf.test_vrf_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "vrf" + parent_dn_key: "tenant_dn" + properties: + name: "vrf_name_1" + - class_name: "fvCtx" + target_dn: "uni/tn-test_tenant/ctx-vrf_name_0" + relation_resource_name: "vrf" + static: false + target_dn_ref: "aci_vrf.test_vrf_1.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "vrf" + parent_dn_key: "tenant_dn" + properties: + name: "vrf_name_0" - class_name: "fvESg" target_dn: "uni/tn-test_tenant/ap-test_ap/esg-esg_0" relation_resource_name: "contract_master" diff --git a/gen/testvars/fvRsBDToNetflowMonitorPol.yaml b/gen/testvars/fvRsBDToNetflowMonitorPol.yaml index 2376f2f0b..9ef2bc1fd 100644 --- a/gen/testvars/fvRsBDToNetflowMonitorPol.yaml +++ b/gen/testvars/fvRsBDToNetflowMonitorPol.yaml @@ -44,4 +44,16 @@ parents: parent_dn: "aci_bridge_domain.test.id" class_in_parent: false test_type: both +targets: + - class_name: "netflowMonitorPol" + target_dn: "uni/tn-test_tenant/monitorpol-netflow_monitor_policy_name_1" + target_dn_ref: "aci_netflow_monitor_policy.test_netflow_monitor_policy_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "netflow_monitor_policy" + relation_resource_name: "netflow_monitor_policy_name" + parent_dn_key: "parent_dn" + static: false + properties: + name: "netflow_monitor_policy_name_1" class_version: 2.2(1k)- diff --git a/gen/testvars/fvRsCons.yaml b/gen/testvars/fvRsCons.yaml index f47cd0bc5..83b156c0f 100644 --- a/gen/testvars/fvRsCons.yaml +++ b/gen/testvars/fvRsCons.yaml @@ -50,4 +50,27 @@ parents: parent_dn: "aci_endpoint_security_group.test.id" class_in_parent: false test_type: both +targets: + - class_name: "vzBrCP" + target_dn: "uni/tn-test_tenant/brc-contract_name_0" + target_dn_ref: "aci_contract.test_contract_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "contract" + relation_resource_name: "contract" + parent_dn_key: "tenant_dn" + static: false + properties: + name: "contract_name_0" + - class_name: "vzBrCP" + target_dn: "uni/tn-test_tenant/brc-contract_name_1" + target_dn_ref: "aci_contract.test_contract_1.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "contract" + relation_resource_name: "contract" + parent_dn_key: "tenant_dn" + static: false + properties: + name: "contract_name_1" class_version: 1.0(1e)- diff --git a/gen/testvars/fvRsConsIf.yaml b/gen/testvars/fvRsConsIf.yaml index 4be226909..65b47acde 100644 --- a/gen/testvars/fvRsConsIf.yaml +++ b/gen/testvars/fvRsConsIf.yaml @@ -50,4 +50,27 @@ parents: parent_dn: "aci_endpoint_security_group.test.id" class_in_parent: false test_type: both +targets: + - class_name: "vzCPIf" + target_dn: "uni/tn-test_tenant/cif-imported_contract_name_0" + target_dn_ref: "aci_imported_contract.test_imported_contract_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "imported_contract" + relation_resource_name: "imported_contract" + parent_dn_key: "tenant_dn" + static: false + properties: + name: "imported_contract_name_0" + - class_name: "vzCPIf" + target_dn: "uni/tn-test_tenant/cif-imported_contract_name_1" + target_dn_ref: "aci_imported_contract.test_imported_contract_1.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "imported_contract" + relation_resource_name: "imported_contract" + parent_dn_key: "tenant_dn" + static: false + properties: + name: "imported_contract_name_1" class_version: 1.0(1e)- diff --git a/gen/testvars/fvRsProtBy.yaml b/gen/testvars/fvRsProtBy.yaml index 5d8ca6662..a5f229041 100644 --- a/gen/testvars/fvRsProtBy.yaml +++ b/gen/testvars/fvRsProtBy.yaml @@ -39,4 +39,27 @@ parents: parent_dn: "aci_application_epg.test.id" class_in_parent: false test_type: both +targets: + - class_name: "vzTaboo" + target_dn: "uni/tn-test_tenant/taboo-taboo_contract_name_0" + target_dn_ref: "aci_taboo_contract.test_taboo_contract_0.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "taboo_contract" + relation_resource_name: "taboo_contract" + parent_dn_key: "tenant_dn" + static: false + properties: + name: "taboo_contract_name_0" + - class_name: "vzTaboo" + target_dn: "uni/tn-test_tenant/taboo-taboo_contract_name_1" + target_dn_ref: "aci_taboo_contract.test_taboo_contract_1.id" + parent_dependency: "fvTenant" + parent_dependency_dn_ref: "aci_tenant.test.id" + target_resource_name: "taboo_contract" + relation_resource_name: "taboo_contract" + parent_dn_key: "tenant_dn" + static: false + properties: + name: "taboo_contract_name_1" class_version: 1.0(1e)- diff --git a/gen/testvars/fvRsSecInherited.yaml b/gen/testvars/fvRsSecInherited.yaml index ad9bb7d49..e8aeaa5c5 100644 --- a/gen/testvars/fvRsSecInherited.yaml +++ b/gen/testvars/fvRsSecInherited.yaml @@ -72,7 +72,7 @@ targets: properties: name: "esg_1" - class_name: "fvAEPg" - target_dn: "uni/tn-test_tenant/ap-test_ap/epg-epg_2" + target_dn: "uni/tn-test_tenant/ap-test_ap/epg-epg_0" target_dn_ref: "aci_application_epg.test_application_epg_0.id" parent_dependency: "fvAp" parent_dependency_dn_ref: "aci_application_profile.test.id" @@ -81,9 +81,9 @@ targets: parent_dn_key: "application_profile_dn" static: false properties: - name: "epg_2" + name: "epg_0" - class_name: "fvAEPg" - target_dn: "uni/tn-test_tenant/ap-test_ap/epg-epg_3" + target_dn: "uni/tn-test_tenant/ap-test_ap/epg-epg_1" target_dn_ref: "aci_application_epg.test_application_epg_1.id" parent_dependency: "fvAp" parent_dependency_dn_ref: "aci_application_profile.test.id" @@ -92,5 +92,5 @@ targets: parent_dn_key: "application_profile_dn" static: false properties: - name: "epg_3" + name: "epg_1" class_version: 2.3(1e)- diff --git a/internal/provider/data_source_aci_application_epg.go b/internal/provider/data_source_aci_application_epg.go index d52f35a4a..203a6d2c2 100644 --- a/internal/provider/data_source_aci_application_epg.go +++ b/internal/provider/data_source_aci_application_epg.go @@ -87,6 +87,11 @@ func (d *FvAEPgDataSource) Schema(ctx context.Context, req datasource.SchemaRequ Computed: true, DeprecationMessage: "Attribute 'shutdown' is deprecated, please refer to 'admin_state' instead. The attribute will be removed in the next major version of the provider.", }, + "relation_fv_rs_path_att": schema.SetAttribute{ + Computed: true, + ElementType: types.StringType, + DeprecationMessage: "Attribute `relation_fv_rs_path_att` is deprecated. The attribute will be removed in the next major version of the provider.", + }, "relation_fv_rs_prov_def": schema.SetAttribute{ Computed: true, ElementType: types.StringType, @@ -138,11 +143,6 @@ func (d *FvAEPgDataSource) Schema(ctx context.Context, req datasource.SchemaRequ ElementType: types.StringType, DeprecationMessage: "Attribute 'relation_fv_rs_prov' is deprecated, please refer to 'relation_to_provided_contracts.contract_name' instead. The attribute will be removed in the next major version of the provider.", }, - "relation_fv_rs_path_att": schema.SetAttribute{ - Computed: true, - ElementType: types.StringType, - DeprecationMessage: "Attribute 'relation_fv_rs_path_att' is deprecated, please refer to 'relation_to_static_paths.target_dn' instead. The attribute will be removed in the next major version of the provider.", - }, "relation_fv_rs_prot_by": schema.SetAttribute{ Computed: true, ElementType: types.StringType, diff --git a/internal/provider/data_source_aci_bridge_domain.go b/internal/provider/data_source_aci_bridge_domain.go index 9144ffe85..521210468 100644 --- a/internal/provider/data_source_aci_bridge_domain.go +++ b/internal/provider/data_source_aci_bridge_domain.go @@ -111,6 +111,10 @@ func (d *FvBDDataSource) Schema(ctx context.Context, req datasource.SchemaReques ElementType: types.StringType, DeprecationMessage: "Attribute `relation_fv_rs_bd_flood_to` is deprecated. The attribute will be removed in the next major version of the provider.", }, + "relation_fv_rs_bd_to_profile": schema.StringAttribute{ + Computed: true, + DeprecationMessage: "Attribute `relation_fv_rs_bd_to_profile` is deprecated. The attribute will be removed in the next major version of the provider.", + }, "relation_fv_rs_bd_to_relay_p": schema.StringAttribute{ Computed: true, DeprecationMessage: "Attribute 'relation_fv_rs_bd_to_relay_p' is deprecated, please refer to 'relation_to_dhcp_relay_policy.dhcp_relay_policy_name' instead. The attribute will be removed in the next major version of the provider.", @@ -144,10 +148,6 @@ func (d *FvBDDataSource) Schema(ctx context.Context, req datasource.SchemaReques Computed: true, DeprecationMessage: "Attribute 'relation_fv_rs_bd_to_nd_p' is deprecated, please refer to 'relation_to_neighbor_discovery_interface_policy.neighbor_discovery_interface_policy_name' instead. The attribute will be removed in the next major version of the provider.", }, - "relation_fv_rs_bd_to_profile": schema.StringAttribute{ - Computed: true, - DeprecationMessage: "Attribute 'relation_fv_rs_bd_to_profile' is deprecated, please refer to 'relation_to_route_control_profile.route_control_profile_name' instead. The attribute will be removed in the next major version of the provider.", - }, "relation_fv_rs_ctx": schema.StringAttribute{ Computed: true, DeprecationMessage: "Attribute 'relation_fv_rs_ctx' is deprecated, please refer to 'relation_to_vrf.vrf_name' instead. The attribute will be removed in the next major version of the provider.", diff --git a/internal/provider/data_source_aci_relation_to_contract_master_test.go b/internal/provider/data_source_aci_relation_to_contract_master_test.go index 399995c3a..90dcf0e45 100644 --- a/internal/provider/data_source_aci_relation_to_contract_master_test.go +++ b/internal/provider/data_source_aci_relation_to_contract_master_test.go @@ -21,7 +21,7 @@ func TestAccDataSourceFvRsSecInheritedWithFvAEPg(t *testing.T) { Config: testConfigFvRsSecInheritedDataSourceDependencyWithFvAEPg, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("data.aci_relation_to_contract_master.test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_2"), + resource.TestCheckResourceAttr("data.aci_relation_to_contract_master.test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_0"), resource.TestCheckResourceAttr("data.aci_relation_to_contract_master.test", "annotation", "orchestrator:terraform"), ), }, @@ -65,7 +65,7 @@ data "aci_relation_to_contract_master" "test" { const testConfigFvRsSecInheritedNotExistingFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` data "aci_relation_to_contract_master" "test_non_existing" { parent_dn = aci_application_epg.test.id - target_dn = "uni/tn-test_tenant/ap-test_ap/epg-epg_2_not_existing" + target_dn = "uni/tn-test_tenant/ap-test_ap/epg-epg_0_not_existing" } ` const testConfigFvRsSecInheritedDataSourceDependencyWithFvESg = testConfigFvRsSecInheritedMinDependencyWithFvESg + ` diff --git a/internal/provider/resource_aci_application_epg.go b/internal/provider/resource_aci_application_epg.go index 459c36299..696530ccc 100644 --- a/internal/provider/resource_aci_application_epg.go +++ b/internal/provider/resource_aci_application_epg.go @@ -93,6 +93,7 @@ type FvAEPgResourceModel struct { DeprecatedPrefGrMemb types.String `tfsdk:"pref_gr_memb"` DeprecatedPrio types.String `tfsdk:"prio"` DeprecatedShutdown types.String `tfsdk:"shutdown"` + Deprecated_relation_fv_rs_path_att types.Set `tfsdk:"relation_fv_rs_path_att"` Deprecated_relation_fv_rs_prov_def types.Set `tfsdk:"relation_fv_rs_prov_def"` DeprecatedFvRsAEPgMonPol types.String `tfsdk:"relation_fv_rs_aepg_mon_pol"` DeprecatedFvRsBd types.String `tfsdk:"relation_fv_rs_bd"` @@ -104,7 +105,6 @@ type FvAEPgResourceModel struct { DeprecatedFvRsConsIf types.Set `tfsdk:"relation_fv_rs_cons_if"` DeprecatedFvRsIntraEpg types.Set `tfsdk:"relation_fv_rs_intra_epg"` DeprecatedFvRsProv types.Set `tfsdk:"relation_fv_rs_prov"` - DeprecatedFvRsPathAtt types.Set `tfsdk:"relation_fv_rs_path_att"` DeprecatedFvRsProtBy types.Set `tfsdk:"relation_fv_rs_prot_by"` DeprecatedFvRsTrustCtrl types.String `tfsdk:"relation_fv_rs_trust_ctrl"` DeprecatedFvRsNodeAtt types.Set `tfsdk:"relation_fv_rs_node_att"` @@ -315,6 +315,7 @@ func getEmptyFvAEPgResourceModel() *FvAEPgResourceModel { DeprecatedPrefGrMemb: types.String{}, DeprecatedPrio: types.String{}, DeprecatedShutdown: types.String{}, + Deprecated_relation_fv_rs_path_att: types.SetNull(types.StringType), Deprecated_relation_fv_rs_prov_def: types.SetNull(types.StringType), DeprecatedFvRsAEPgMonPol: types.String{}, DeprecatedFvRsBd: types.String{}, @@ -326,7 +327,6 @@ func getEmptyFvAEPgResourceModel() *FvAEPgResourceModel { DeprecatedFvRsConsIf: types.SetNull(types.StringType), DeprecatedFvRsIntraEpg: types.SetNull(types.StringType), DeprecatedFvRsProv: types.SetNull(types.StringType), - DeprecatedFvRsPathAtt: types.SetNull(types.StringType), DeprecatedFvRsProtBy: types.SetNull(types.StringType), DeprecatedFvRsTrustCtrl: types.String{}, DeprecatedFvRsNodeAtt: types.SetNull(deprecatedFvRsNodeAttType), @@ -615,6 +615,39 @@ var FvRsConsFvAEPgType = types.ObjectType{ }, } +func FvRsConsFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsConsFvAEPgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.Prio.IsNull() { + nullInStateFound = true + planSetValues[index].Prio = customTypes.NewFvRsConsPrioStringNull() + } + if stateValue.TnVzBrCPName.IsNull() { + nullInStateFound = true + planSetValues[index].TnVzBrCPName = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsConsFvAEPgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsConsFvAEPgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsConsFvAEPgResourceModel struct { Key types.String `tfsdk:"key"` @@ -694,6 +727,39 @@ var FvRsConsIfFvAEPgType = types.ObjectType{ }, } +func FvRsConsIfFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsConsIfFvAEPgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.Prio.IsNull() { + nullInStateFound = true + planSetValues[index].Prio = customTypes.NewFvRsConsIfPrioStringNull() + } + if stateValue.TnVzCPIfName.IsNull() { + nullInStateFound = true + planSetValues[index].TnVzCPIfName = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsConsIfFvAEPgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsConsIfFvAEPgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsConsIfFvAEPgResourceModel struct { Key types.String `tfsdk:"key"` @@ -913,6 +979,127 @@ var FvRsDomAttFvAEPgType = types.ObjectType{ }, } +func FvRsDomAttFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsDomAttFvAEPgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.BindingType.IsNull() { + nullInStateFound = true + planSetValues[index].BindingType = basetypes.NewStringNull() + } + if stateValue.ClassPref.IsNull() { + nullInStateFound = true + planSetValues[index].ClassPref = basetypes.NewStringNull() + } + if stateValue.CustomEpgName.IsNull() { + nullInStateFound = true + planSetValues[index].CustomEpgName = basetypes.NewStringNull() + } + if stateValue.Delimiter.IsNull() { + nullInStateFound = true + planSetValues[index].Delimiter = basetypes.NewStringNull() + } + if stateValue.Encap.IsNull() { + nullInStateFound = true + planSetValues[index].Encap = basetypes.NewStringNull() + } + if stateValue.EncapMode.IsNull() { + nullInStateFound = true + planSetValues[index].EncapMode = basetypes.NewStringNull() + } + if stateValue.EpgCos.IsNull() { + nullInStateFound = true + planSetValues[index].EpgCos = basetypes.NewStringNull() + } + if stateValue.EpgCosPref.IsNull() { + nullInStateFound = true + planSetValues[index].EpgCosPref = basetypes.NewStringNull() + } + if stateValue.InstrImedcy.IsNull() { + nullInStateFound = true + planSetValues[index].InstrImedcy = basetypes.NewStringNull() + } + if stateValue.IpamDhcpOverride.IsNull() { + nullInStateFound = true + planSetValues[index].IpamDhcpOverride = basetypes.NewStringNull() + } + if stateValue.IpamEnabled.IsNull() { + nullInStateFound = true + planSetValues[index].IpamEnabled = basetypes.NewStringNull() + } + if stateValue.IpamGateway.IsNull() { + nullInStateFound = true + planSetValues[index].IpamGateway = basetypes.NewStringNull() + } + if stateValue.LagPolicyName.IsNull() { + nullInStateFound = true + planSetValues[index].LagPolicyName = basetypes.NewStringNull() + } + if stateValue.NetflowDir.IsNull() { + nullInStateFound = true + planSetValues[index].NetflowDir = basetypes.NewStringNull() + } + if stateValue.NetflowPref.IsNull() { + nullInStateFound = true + planSetValues[index].NetflowPref = basetypes.NewStringNull() + } + if stateValue.NumPorts.IsNull() { + nullInStateFound = true + planSetValues[index].NumPorts = basetypes.NewStringNull() + } + if stateValue.PortAllocation.IsNull() { + nullInStateFound = true + planSetValues[index].PortAllocation = basetypes.NewStringNull() + } + if stateValue.PrimaryEncap.IsNull() { + nullInStateFound = true + planSetValues[index].PrimaryEncap = basetypes.NewStringNull() + } + if stateValue.PrimaryEncapInner.IsNull() { + nullInStateFound = true + planSetValues[index].PrimaryEncapInner = basetypes.NewStringNull() + } + if stateValue.ResImedcy.IsNull() { + nullInStateFound = true + planSetValues[index].ResImedcy = basetypes.NewStringNull() + } + if stateValue.SecondaryEncapInner.IsNull() { + nullInStateFound = true + planSetValues[index].SecondaryEncapInner = basetypes.NewStringNull() + } + if stateValue.SwitchingMode.IsNull() { + nullInStateFound = true + planSetValues[index].SwitchingMode = basetypes.NewStringNull() + } + if stateValue.TDn.IsNull() { + nullInStateFound = true + planSetValues[index].TDn = basetypes.NewStringNull() + } + if stateValue.Untagged.IsNull() { + nullInStateFound = true + planSetValues[index].Untagged = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsDomAttFvAEPgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsDomAttFvAEPgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsDomAttFvAEPgResourceModel struct { Key types.String `tfsdk:"key"` @@ -1072,6 +1259,47 @@ var FvRsFcPathAttFvAEPgType = types.ObjectType{ }, } +func FvRsFcPathAttFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsFcPathAttFvAEPgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.Descr.IsNull() { + nullInStateFound = true + planSetValues[index].Descr = basetypes.NewStringNull() + } + if stateValue.TDn.IsNull() { + nullInStateFound = true + planSetValues[index].TDn = basetypes.NewStringNull() + } + if stateValue.Vsan.IsNull() { + nullInStateFound = true + planSetValues[index].Vsan = basetypes.NewStringNull() + } + if stateValue.VsanMode.IsNull() { + nullInStateFound = true + planSetValues[index].VsanMode = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsFcPathAttFvAEPgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsFcPathAttFvAEPgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsFcPathAttFvAEPgResourceModel struct { Key types.String `tfsdk:"key"` @@ -1148,6 +1376,35 @@ var FvRsIntraEpgFvAEPgType = types.ObjectType{ }, } +func FvRsIntraEpgFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsIntraEpgFvAEPgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.TnVzBrCPName.IsNull() { + nullInStateFound = true + planSetValues[index].TnVzBrCPName = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsIntraEpgFvAEPgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsIntraEpgFvAEPgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsIntraEpgFvAEPgResourceModel struct { Key types.String `tfsdk:"key"` @@ -1236,6 +1493,51 @@ var FvRsNodeAttFvAEPgType = types.ObjectType{ }, } +func FvRsNodeAttFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsNodeAttFvAEPgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.Descr.IsNull() { + nullInStateFound = true + planSetValues[index].Descr = basetypes.NewStringNull() + } + if stateValue.Encap.IsNull() { + nullInStateFound = true + planSetValues[index].Encap = basetypes.NewStringNull() + } + if stateValue.InstrImedcy.IsNull() { + nullInStateFound = true + planSetValues[index].InstrImedcy = basetypes.NewStringNull() + } + if stateValue.Mode.IsNull() { + nullInStateFound = true + planSetValues[index].Mode = basetypes.NewStringNull() + } + if stateValue.TDn.IsNull() { + nullInStateFound = true + planSetValues[index].TDn = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsNodeAttFvAEPgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsNodeAttFvAEPgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsNodeAttFvAEPgResourceModel struct { Key types.String `tfsdk:"key"` @@ -1327,6 +1629,55 @@ var FvRsPathAttFvAEPgType = types.ObjectType{ }, } +func FvRsPathAttFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsPathAttFvAEPgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.Descr.IsNull() { + nullInStateFound = true + planSetValues[index].Descr = basetypes.NewStringNull() + } + if stateValue.Encap.IsNull() { + nullInStateFound = true + planSetValues[index].Encap = basetypes.NewStringNull() + } + if stateValue.InstrImedcy.IsNull() { + nullInStateFound = true + planSetValues[index].InstrImedcy = basetypes.NewStringNull() + } + if stateValue.Mode.IsNull() { + nullInStateFound = true + planSetValues[index].Mode = basetypes.NewStringNull() + } + if stateValue.PrimaryEncap.IsNull() { + nullInStateFound = true + planSetValues[index].PrimaryEncap = basetypes.NewStringNull() + } + if stateValue.TDn.IsNull() { + nullInStateFound = true + planSetValues[index].TDn = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsPathAttFvAEPgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsPathAttFvAEPgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsPathAttFvAEPgResourceModel struct { Key types.String `tfsdk:"key"` @@ -1403,6 +1754,35 @@ var FvRsProtByFvAEPgType = types.ObjectType{ }, } +func FvRsProtByFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsProtByFvAEPgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.TnVzTabooName.IsNull() { + nullInStateFound = true + planSetValues[index].TnVzTabooName = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsProtByFvAEPgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsProtByFvAEPgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsProtByFvAEPgResourceModel struct { Key types.String `tfsdk:"key"` @@ -1485,6 +1865,43 @@ var FvRsProvFvAEPgType = types.ObjectType{ }, } +func FvRsProvFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsProvFvAEPgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.MatchT.IsNull() { + nullInStateFound = true + planSetValues[index].MatchT = basetypes.NewStringNull() + } + if stateValue.Prio.IsNull() { + nullInStateFound = true + planSetValues[index].Prio = customTypes.NewFvRsProvPrioStringNull() + } + if stateValue.TnVzBrCPName.IsNull() { + nullInStateFound = true + planSetValues[index].TnVzBrCPName = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsProvFvAEPgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsProvFvAEPgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsProvFvAEPgResourceModel struct { Key types.String `tfsdk:"key"` @@ -1561,6 +1978,35 @@ var FvRsSecInheritedFvAEPgType = types.ObjectType{ }, } +func FvRsSecInheritedFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsSecInheritedFvAEPgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.TDn.IsNull() { + nullInStateFound = true + planSetValues[index].TDn = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsSecInheritedFvAEPgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsSecInheritedFvAEPgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsSecInheritedFvAEPgResourceModel struct { Key types.String `tfsdk:"key"` @@ -1746,6 +2192,7 @@ type FvAEPgResourceModelV1 struct { PrefGrMemb types.String `tfsdk:"pref_gr_memb"` Prio types.String `tfsdk:"prio"` Shutdown types.String `tfsdk:"shutdown"` + Deprecated_relation_fv_rs_path_att types.Set `tfsdk:"relation_fv_rs_path_att"` Deprecated_relation_fv_rs_prov_def types.Set `tfsdk:"relation_fv_rs_prov_def"` FvRsAEPgMonPol types.String `tfsdk:"relation_fv_rs_aepg_mon_pol"` FvRsBd types.String `tfsdk:"relation_fv_rs_bd"` @@ -1757,7 +2204,6 @@ type FvAEPgResourceModelV1 struct { FvRsConsIf types.Set `tfsdk:"relation_fv_rs_cons_if"` FvRsIntraEpg types.Set `tfsdk:"relation_fv_rs_intra_epg"` FvRsProv types.Set `tfsdk:"relation_fv_rs_prov"` - FvRsPathAtt types.Set `tfsdk:"relation_fv_rs_path_att"` FvRsProtBy types.Set `tfsdk:"relation_fv_rs_prot_by"` FvRsTrustCtrl types.String `tfsdk:"relation_fv_rs_trust_ctrl"` FvRsNodeAtt types.Set `tfsdk:"relation_fv_rs_node_att"` @@ -1771,6 +2217,16 @@ type FvRsNodeAttFvAEPgResourceModelV1 struct { TDn types.String `tfsdk:"node_dn"` } +func getEmptyFvRsNodeAttFvAEPgResourceModelV1() FvRsNodeAttFvAEPgResourceModelV1 { + return FvRsNodeAttFvAEPgResourceModelV1{ + InstrImedcy: basetypes.NewStringNull(), + Descr: basetypes.NewStringNull(), + Encap: basetypes.NewStringNull(), + Mode: basetypes.NewStringNull(), + TDn: basetypes.NewStringNull(), + } +} + func (r *FvAEPgResource) UpgradeState(ctx context.Context) map[int64]resource.StateUpgrader { return map[int64]resource.StateUpgrader{ 1: { @@ -1856,6 +2312,12 @@ func (r *FvAEPgResource) UpgradeState(ctx context.Context) map[int64]resource.St Optional: true, Computed: true, }, + "relation_fv_rs_path_att": schema.SetAttribute{ + Required: false, + Optional: true, + Computed: false, + ElementType: types.StringType, + }, "relation_fv_rs_prov_def": schema.SetAttribute{ Required: false, Optional: true, @@ -1918,12 +2380,6 @@ func (r *FvAEPgResource) UpgradeState(ctx context.Context) map[int64]resource.St Computed: false, ElementType: types.StringType, }, - "relation_fv_rs_path_att": schema.SetAttribute{ - Required: false, - Optional: true, - Computed: false, - ElementType: types.StringType, - }, "relation_fv_rs_prot_by": schema.SetAttribute{ Required: false, Optional: true, @@ -2009,6 +2465,7 @@ func (r *FvAEPgResource) UpgradeState(ctx context.Context) map[int64]resource.St DeprecatedPrefGrMemb: priorStateData.PrefGrMemb, DeprecatedPrio: priorStateData.Prio, DeprecatedShutdown: priorStateData.Shutdown, + Deprecated_relation_fv_rs_path_att: priorStateData.Deprecated_relation_fv_rs_path_att, Deprecated_relation_fv_rs_prov_def: priorStateData.Deprecated_relation_fv_rs_prov_def, DeprecatedFvRsAEPgMonPol: priorStateData.FvRsAEPgMonPol, DeprecatedFvRsBd: priorStateData.FvRsBd, @@ -2261,34 +2718,21 @@ func (r *FvAEPgResource) UpgradeState(ctx context.Context) map[int64]resource.St FvRsNodeAttSet, _ := types.SetValueFrom(ctx, FvRsNodeAttFvAEPgType, FvRsNodeAttList) upgradedStateData.FvRsNodeAtt = FvRsNodeAttSet - FvRsPathAttList := make([]FvRsPathAttFvAEPgResourceModel, 0) - var priorStateDataFvRsPathAttList []string - priorStateData.FvRsPathAtt.ElementsAs(ctx, &priorStateDataFvRsPathAttList, false) - for _, priorStateDataFvRsPathAtt := range priorStateDataFvRsPathAttList { - FvRsPathAtt := FvRsPathAttFvAEPgResourceModel{ - Annotation: basetypes.NewStringNull(), - Descr: basetypes.NewStringNull(), - InstrImedcy: basetypes.NewStringNull(), - Mode: basetypes.NewStringNull(), - PrimaryEncap: basetypes.NewStringNull(), - TDn: basetypes.NewStringValue(priorStateDataFvRsPathAtt), - TagAnnotation: basetypes.NewSetNull(types.ObjectType{ - AttrTypes: map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - }, - }), - TagTag: basetypes.NewSetNull(types.ObjectType{ - AttrTypes: map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - }, - }), - } - FvRsPathAttList = append(FvRsPathAttList, FvRsPathAtt) - } - FvRsPathAttSet, _ := types.SetValueFrom(ctx, FvRsPathAttFvAEPgType, FvRsPathAttList) - upgradedStateData.FvRsPathAtt = FvRsPathAttSet + upgradedStateData.FvRsPathAtt = types.SetNull( + types.ObjectType{ + AttrTypes: map[string]attr.Type{ + "annotation": basetypes.StringType{}, + "description": basetypes.StringType{}, + "encapsulation": basetypes.StringType{}, + "deployment_immediacy": basetypes.StringType{}, + "mode": basetypes.StringType{}, + "primary_encapsulation": basetypes.StringType{}, + "target_dn": basetypes.StringType{}, + "annotations": basetypes.SetType{ElemType: TagAnnotationFvRsPathAttFvAEPgType}, + "tags": basetypes.SetType{ElemType: TagTagFvRsPathAttFvAEPgType}, + }, + }, + ) FvRsProtByList := make([]FvRsProtByFvAEPgResourceModel, 0) var priorStateDataFvRsProtByList []string @@ -2432,11 +2876,6 @@ func (r *FvAEPgResource) UpgradeState(ctx context.Context) map[int64]resource.St DeprecatedFvRsProvSet, _ := types.SetValueFrom(ctx, types.StringType, deprecatedFvRsProvList) upgradedStateData.DeprecatedFvRsProv = DeprecatedFvRsProvSet - var deprecatedFvRsPathAttList []string - priorStateData.FvRsPathAtt.ElementsAs(ctx, &deprecatedFvRsPathAttList, false) - DeprecatedFvRsPathAttSet, _ := types.SetValueFrom(ctx, types.StringType, deprecatedFvRsPathAttList) - upgradedStateData.DeprecatedFvRsPathAtt = DeprecatedFvRsPathAttSet - var deprecatedFvRsProtByList []string priorStateData.FvRsProtBy.ElementsAs(ctx, &deprecatedFvRsProtByList, false) DeprecatedFvRsProtBySet, _ := types.SetValueFrom(ctx, types.StringType, deprecatedFvRsProtByList) @@ -2455,6 +2894,12 @@ func (r *FvAEPgResource) UpgradeState(ctx context.Context) map[int64]resource.St func setFvAEPgLegacyAttributes(ctx context.Context, diags *diag.Diagnostics, data, staticData *FvAEPgResourceModel, classReadInfo []interface{}) { data.DeprecatedParentDn = data.ParentDn + if !staticData.Deprecated_relation_fv_rs_path_att.IsUnknown() && !staticData.Deprecated_relation_fv_rs_path_att.IsNull() { + data.Deprecated_relation_fv_rs_path_att = staticData.Deprecated_relation_fv_rs_path_att + } else { + Deprecated_relation_fv_rs_path_attSet, _ := types.SetValueFrom(ctx, types.StringType, []string{}) + data.Deprecated_relation_fv_rs_path_att = Deprecated_relation_fv_rs_path_attSet + } if !staticData.Deprecated_relation_fv_rs_prov_def.IsUnknown() && !staticData.Deprecated_relation_fv_rs_prov_def.IsNull() { data.Deprecated_relation_fv_rs_prov_def = staticData.Deprecated_relation_fv_rs_prov_def } else { @@ -2504,7 +2949,7 @@ func setFvAEPgLegacyAttributes(ctx context.Context, diags *diag.Diagnostics, dat data.DeprecatedFvRsDppPol = basetypes.NewStringNull() DeprecatedFvRsFcPathAttFvAEPgList := make([]string, 0) DeprecatedFvRsIntraEpgFvAEPgList := make([]string, 0) - DeprecatedFvRsPathAttFvAEPgList := make([]string, 0) + DeprecatedFvRsNodeAttFvAEPgList := make([]FvRsNodeAttFvAEPgResourceModelV1, 0) DeprecatedFvRsProtByFvAEPgList := make([]string, 0) DeprecatedFvRsProvFvAEPgList := make([]string, 0) DeprecatedFvRsSecInheritedFvAEPgList := make([]string, 0) @@ -2572,12 +3017,26 @@ func setFvAEPgLegacyAttributes(ctx context.Context, diags *diag.Diagnostics, dat } } } - if childClassName == "fvRsPathAtt" { + if childClassName == "fvRsNodeAtt" { + DeprecatedFvRsNodeAttFvAEPg := getEmptyFvRsNodeAttFvAEPgResourceModelV1() for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "tDn" && childAttributeValue != "" && !ContainsString(DeprecatedFvRsPathAttFvAEPgList, childAttributeValue.(string)) { - DeprecatedFvRsPathAttFvAEPgList = append(DeprecatedFvRsPathAttFvAEPgList, childAttributeValue.(string)) + if childAttributeName == "descr" { + DeprecatedFvRsNodeAttFvAEPg.Descr = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "encap" { + DeprecatedFvRsNodeAttFvAEPg.Encap = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "instrImedcy" { + DeprecatedFvRsNodeAttFvAEPg.InstrImedcy = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "mode" { + DeprecatedFvRsNodeAttFvAEPg.Mode = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "tDn" { + DeprecatedFvRsNodeAttFvAEPg.TDn = basetypes.NewStringValue(childAttributeValue.(string)) } } + DeprecatedFvRsNodeAttFvAEPgList = append(DeprecatedFvRsNodeAttFvAEPgList, DeprecatedFvRsNodeAttFvAEPg) } if childClassName == "fvRsProtBy" { for childAttributeName, childAttributeValue := range childAttributes { @@ -2617,9 +3076,8 @@ func setFvAEPgLegacyAttributes(ctx context.Context, diags *diag.Diagnostics, dat data.DeprecatedFvRsFcPathAtt = fvRsFcPathAttSet fvRsIntraEpgSet, _ := types.SetValueFrom(ctx, data.DeprecatedFvRsIntraEpg.ElementType(ctx), DeprecatedFvRsIntraEpgFvAEPgList) data.DeprecatedFvRsIntraEpg = fvRsIntraEpgSet - data.DeprecatedFvRsNodeAtt = types.SetNull(deprecatedFvRsNodeAttType) - fvRsPathAttSet, _ := types.SetValueFrom(ctx, data.DeprecatedFvRsPathAtt.ElementType(ctx), DeprecatedFvRsPathAttFvAEPgList) - data.DeprecatedFvRsPathAtt = fvRsPathAttSet + fvRsNodeAttSet, _ := types.SetValueFrom(ctx, data.DeprecatedFvRsNodeAtt.ElementType(ctx), DeprecatedFvRsNodeAttFvAEPgList) + data.DeprecatedFvRsNodeAtt = fvRsNodeAttSet fvRsProtBySet, _ := types.SetValueFrom(ctx, data.DeprecatedFvRsProtBy.ElementType(ctx), DeprecatedFvRsProtByFvAEPgList) data.DeprecatedFvRsProtBy = fvRsProtBySet fvRsProvSet, _ := types.SetValueFrom(ctx, data.DeprecatedFvRsProv.ElementType(ctx), DeprecatedFvRsProvFvAEPgList) @@ -2687,124 +3145,56 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan } } - if !configData.ExceptionTag.IsNull() { - planData.DeprecatedExceptionTag = configData.ExceptionTag - } else if !configData.DeprecatedExceptionTag.IsNull() { + if !configData.DeprecatedExceptionTag.IsNull() { planData.ExceptionTag = configData.DeprecatedExceptionTag - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedExceptionTag = stateData.DeprecatedExceptionTag } - if !configData.FloodOnEncap.IsNull() { - planData.DeprecatedFloodOnEncap = configData.FloodOnEncap - } else if !configData.DeprecatedFloodOnEncap.IsNull() { + if !configData.DeprecatedFloodOnEncap.IsNull() { planData.FloodOnEncap = configData.DeprecatedFloodOnEncap - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFloodOnEncap = stateData.DeprecatedFloodOnEncap } - if !configData.FwdCtrl.IsNull() { - planData.DeprecatedFwdCtrl = configData.FwdCtrl - } else if !configData.DeprecatedFwdCtrl.IsNull() { + if !configData.DeprecatedFwdCtrl.IsNull() { planData.FwdCtrl = configData.DeprecatedFwdCtrl - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFwdCtrl = stateData.DeprecatedFwdCtrl } - if !configData.HasMcastSource.IsNull() { - planData.DeprecatedHasMcastSource = configData.HasMcastSource - } else if !configData.DeprecatedHasMcastSource.IsNull() { + if !configData.DeprecatedHasMcastSource.IsNull() { planData.HasMcastSource = configData.DeprecatedHasMcastSource - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedHasMcastSource = stateData.DeprecatedHasMcastSource } - if !configData.IsAttrBasedEPg.IsNull() { - planData.DeprecatedIsAttrBasedEPg = configData.IsAttrBasedEPg - } else if !configData.DeprecatedIsAttrBasedEPg.IsNull() { + if !configData.DeprecatedIsAttrBasedEPg.IsNull() { planData.IsAttrBasedEPg = configData.DeprecatedIsAttrBasedEPg - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedIsAttrBasedEPg = stateData.DeprecatedIsAttrBasedEPg } - if !configData.MatchT.IsNull() { - planData.DeprecatedMatchT = configData.MatchT - } else if !configData.DeprecatedMatchT.IsNull() { + if !configData.DeprecatedMatchT.IsNull() { planData.MatchT = configData.DeprecatedMatchT - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedMatchT = stateData.DeprecatedMatchT } - if !configData.ParentDn.IsNull() { - planData.DeprecatedParentDn = configData.ParentDn - } else if !configData.DeprecatedParentDn.IsNull() { + if !configData.DeprecatedParentDn.IsNull() { planData.ParentDn = configData.DeprecatedParentDn - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedParentDn = stateData.DeprecatedParentDn } - if !configData.PcEnfPref.IsNull() { - planData.DeprecatedPcEnfPref = configData.PcEnfPref - } else if !configData.DeprecatedPcEnfPref.IsNull() { + if !configData.DeprecatedPcEnfPref.IsNull() { planData.PcEnfPref = configData.DeprecatedPcEnfPref - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedPcEnfPref = stateData.DeprecatedPcEnfPref } - if !configData.PrefGrMemb.IsNull() { - planData.DeprecatedPrefGrMemb = configData.PrefGrMemb - } else if !configData.DeprecatedPrefGrMemb.IsNull() { + if !configData.DeprecatedPrefGrMemb.IsNull() { planData.PrefGrMemb = configData.DeprecatedPrefGrMemb - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedPrefGrMemb = stateData.DeprecatedPrefGrMemb - } - - if !configData.Prio.IsNull() { - matchMap := map[string]string{ - "0": "unspecified", - "1": "level3", - "2": "level2", - "3": "level1", - "7": "level6", - "8": "level5", - "9": "level4", - } - if configDataPrio, ok := matchMap[configData.Prio.ValueString()]; ok { - planData.DeprecatedPrio = basetypes.NewStringValue(configDataPrio) - } else { - planData.DeprecatedPrio = configData.Prio.StringValue - } - } else if !configData.DeprecatedPrio.IsNull() { + } + + if !configData.DeprecatedPrio.IsNull() { planData.Prio = customTypes.FvAEPgPrioStringValue{StringValue: configData.DeprecatedPrio} - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedPrio = stateData.DeprecatedPrio } - if !configData.Shutdown.IsNull() { - planData.DeprecatedShutdown = configData.Shutdown - } else if !configData.DeprecatedShutdown.IsNull() { + if !configData.DeprecatedShutdown.IsNull() { planData.Shutdown = configData.DeprecatedShutdown - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedShutdown = stateData.DeprecatedShutdown } - if !configData.FvRsAEPgMonPol.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsAEPgMonPol.Attributes()) { - planData.FvRsAEPgMonPol = configData.FvRsAEPgMonPol - planData.DeprecatedFvRsAEPgMonPol = basetypes.NewStringNull() - } else { - var attributeValues FvRsAEPgMonPolFvAEPgResourceModel - configData.FvRsAEPgMonPol.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsAEPgMonPol.ValueString()) == attributeValues.TnMonEPGPolName.ValueString() && !attributeValues.TnMonEPGPolName.IsNull() { - planData.DeprecatedFvRsAEPgMonPol = stateData.DeprecatedFvRsAEPgMonPol - } - } - } else if !configData.DeprecatedFvRsAEPgMonPol.IsNull() { + if !configData.DeprecatedFvRsAEPgMonPol.IsNull() { var newAttributeValues FvRsAEPgMonPolFvAEPgResourceModel tagAnnotationFvRsAEPgMonPolFvAEPgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsAEPgMonPolFvAEPgType, make([]TagAnnotationFvRsAEPgMonPolFvAEPgResourceModel, 0)) tagTagFvRsAEPgMonPolFvAEPgValue, _ := types.SetValueFrom(ctx, TagTagFvRsAEPgMonPolFvAEPgType, make([]TagTagFvRsAEPgMonPolFvAEPgResourceModel, 0)) annotationValue := planData.Annotation - if stateData != nil { + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.FvRsAEPgMonPol.Attributes()) { stateData.FvRsAEPgMonPol.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) annotationValue = newAttributeValues.Annotation tagAnnotationFvRsAEPgMonPolFvAEPgValue = newAttributeValues.TagAnnotation @@ -2822,27 +3212,14 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan } FvRsAEPgMonPolObject, _ := types.ObjectValueFrom(ctx, FvRsAEPgMonPolFvAEPgType, FvRsAEPgMonPol) planData.FvRsAEPgMonPol = FvRsAEPgMonPolObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsAEPgMonPol = stateData.DeprecatedFvRsAEPgMonPol } - if !configData.FvRsBd.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsBd.Attributes()) { - planData.FvRsBd = configData.FvRsBd - planData.DeprecatedFvRsBd = basetypes.NewStringNull() - } else { - var attributeValues FvRsBdFvAEPgResourceModel - configData.FvRsBd.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsBd.ValueString()) == attributeValues.TnFvBDName.ValueString() && !attributeValues.TnFvBDName.IsNull() { - planData.DeprecatedFvRsBd = stateData.DeprecatedFvRsBd - } - } - } else if !configData.DeprecatedFvRsBd.IsNull() { + if !configData.DeprecatedFvRsBd.IsNull() { var newAttributeValues FvRsBdFvAEPgResourceModel tagAnnotationFvRsBdFvAEPgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsBdFvAEPgType, make([]TagAnnotationFvRsBdFvAEPgResourceModel, 0)) tagTagFvRsBdFvAEPgValue, _ := types.SetValueFrom(ctx, TagTagFvRsBdFvAEPgType, make([]TagTagFvRsBdFvAEPgResourceModel, 0)) annotationValue := planData.Annotation - if stateData != nil { + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.FvRsBd.Attributes()) { stateData.FvRsBd.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) annotationValue = newAttributeValues.Annotation tagAnnotationFvRsBdFvAEPgValue = newAttributeValues.TagAnnotation @@ -2860,37 +3237,13 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan } FvRsBdObject, _ := types.ObjectValueFrom(ctx, FvRsBdFvAEPgType, FvRsBd) planData.FvRsBd = FvRsBdObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsBd = stateData.DeprecatedFvRsBd } - if !configData.FvRsCons.IsNull() && stateData != nil { - var attributeValues []FvRsConsFvAEPgResourceModel - var newAttributeValues, stateAttributeValues []string - configData.FvRsCons.ElementsAs(ctx, &attributeValues, false) - stateData.DeprecatedFvRsCons.ElementsAs(ctx, &stateAttributeValues, false) - for _, attributeValue := range attributeValues { - newAttributeValues = append(newAttributeValues, attributeValue.TnVzBrCPName.ValueString()) - } - - if len(newAttributeValues) == len(stateAttributeValues) { - allMatchState := true - for _, stateAttributeValue := range stateAttributeValues { - if !ContainsString(newAttributeValues, GetMOName(stateAttributeValue)) { - allMatchState = false - break - } - } - if allMatchState { - FvRsConsSet, _ := types.SetValueFrom(ctx, basetypes.StringType{}, stateAttributeValues) - planData.DeprecatedFvRsCons = FvRsConsSet - } - } - } else if !configData.DeprecatedFvRsCons.IsNull() { + if !configData.DeprecatedFvRsCons.IsNull() { FvRsConsList := make([]FvRsConsFvAEPgResourceModel, 0) var attributeValues []basetypes.StringValue var newAttributeValues []FvRsConsFvAEPgResourceModel - configData.DeprecatedFvRsCons.ElementsAs(ctx, &attributeValues, false) + planData.DeprecatedFvRsCons.ElementsAs(ctx, &attributeValues, false) if stateData != nil { stateData.FvRsCons.ElementsAs(ctx, &newAttributeValues, false) } @@ -2917,7 +3270,7 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan FvRsCons.Prio = FvRsConsValue.Prio } else { FvRsCons.Annotation = planData.Annotation - FvRsCons.Prio = customTypes.NewFvRsConsPrioStringValue("unspecified") // Default to default value from meta when not found + FvRsCons.Prio = customTypes.NewFvRsConsPrioStringUnknown() } tagAnnotationFvRsConsFvAEPgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsConsFvAEPgType, make([]TagAnnotationFvRsConsFvAEPgResourceModel, 0)) FvRsCons.TagAnnotation = tagAnnotationFvRsConsFvAEPgValue @@ -2927,37 +3280,13 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan } FvRsConsSet, _ := types.SetValueFrom(ctx, FvRsConsFvAEPgType, FvRsConsList) planData.FvRsCons = FvRsConsSet - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsCons = stateData.DeprecatedFvRsCons } - if !configData.FvRsSecInherited.IsNull() && stateData != nil { - var attributeValues []FvRsSecInheritedFvAEPgResourceModel - var newAttributeValues, stateAttributeValues []string - configData.FvRsSecInherited.ElementsAs(ctx, &attributeValues, false) - stateData.DeprecatedFvRsSecInherited.ElementsAs(ctx, &stateAttributeValues, false) - for _, attributeValue := range attributeValues { - newAttributeValues = append(newAttributeValues, attributeValue.TDn.ValueString()) - } - - if len(newAttributeValues) == len(stateAttributeValues) { - allMatchState := true - for _, stateAttributeValue := range stateAttributeValues { - if !ContainsString(newAttributeValues, GetMOName(stateAttributeValue)) { - allMatchState = false - break - } - } - if allMatchState { - FvRsSecInheritedSet, _ := types.SetValueFrom(ctx, basetypes.StringType{}, stateAttributeValues) - planData.DeprecatedFvRsSecInherited = FvRsSecInheritedSet - } - } - } else if !configData.DeprecatedFvRsSecInherited.IsNull() { + if !configData.DeprecatedFvRsSecInherited.IsNull() { FvRsSecInheritedList := make([]FvRsSecInheritedFvAEPgResourceModel, 0) var attributeValues []basetypes.StringValue var newAttributeValues []FvRsSecInheritedFvAEPgResourceModel - configData.DeprecatedFvRsSecInherited.ElementsAs(ctx, &attributeValues, false) + planData.DeprecatedFvRsSecInherited.ElementsAs(ctx, &attributeValues, false) if stateData != nil { stateData.FvRsSecInherited.ElementsAs(ctx, &newAttributeValues, false) } @@ -2992,27 +3321,14 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan } FvRsSecInheritedSet, _ := types.SetValueFrom(ctx, FvRsSecInheritedFvAEPgType, FvRsSecInheritedList) planData.FvRsSecInherited = FvRsSecInheritedSet - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsSecInherited = stateData.DeprecatedFvRsSecInherited } - if !configData.FvRsCustQosPol.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsCustQosPol.Attributes()) { - planData.FvRsCustQosPol = configData.FvRsCustQosPol - planData.DeprecatedFvRsCustQosPol = basetypes.NewStringNull() - } else { - var attributeValues FvRsCustQosPolFvAEPgResourceModel - configData.FvRsCustQosPol.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsCustQosPol.ValueString()) == attributeValues.TnQosCustomPolName.ValueString() && !attributeValues.TnQosCustomPolName.IsNull() { - planData.DeprecatedFvRsCustQosPol = stateData.DeprecatedFvRsCustQosPol - } - } - } else if !configData.DeprecatedFvRsCustQosPol.IsNull() { + if !configData.DeprecatedFvRsCustQosPol.IsNull() { var newAttributeValues FvRsCustQosPolFvAEPgResourceModel tagAnnotationFvRsCustQosPolFvAEPgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsCustQosPolFvAEPgType, make([]TagAnnotationFvRsCustQosPolFvAEPgResourceModel, 0)) tagTagFvRsCustQosPolFvAEPgValue, _ := types.SetValueFrom(ctx, TagTagFvRsCustQosPolFvAEPgType, make([]TagTagFvRsCustQosPolFvAEPgResourceModel, 0)) annotationValue := planData.Annotation - if stateData != nil { + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.FvRsCustQosPol.Attributes()) { stateData.FvRsCustQosPol.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) annotationValue = newAttributeValues.Annotation tagAnnotationFvRsCustQosPolFvAEPgValue = newAttributeValues.TagAnnotation @@ -3030,27 +3346,14 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan } FvRsCustQosPolObject, _ := types.ObjectValueFrom(ctx, FvRsCustQosPolFvAEPgType, FvRsCustQosPol) planData.FvRsCustQosPol = FvRsCustQosPolObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsCustQosPol = stateData.DeprecatedFvRsCustQosPol } - if !configData.FvRsDppPol.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsDppPol.Attributes()) { - planData.FvRsDppPol = configData.FvRsDppPol - planData.DeprecatedFvRsDppPol = basetypes.NewStringNull() - } else { - var attributeValues FvRsDppPolFvAEPgResourceModel - configData.FvRsDppPol.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsDppPol.ValueString()) == attributeValues.TnQosDppPolName.ValueString() && !attributeValues.TnQosDppPolName.IsNull() { - planData.DeprecatedFvRsDppPol = stateData.DeprecatedFvRsDppPol - } - } - } else if !configData.DeprecatedFvRsDppPol.IsNull() { + if !configData.DeprecatedFvRsDppPol.IsNull() { var newAttributeValues FvRsDppPolFvAEPgResourceModel tagAnnotationFvRsDppPolFvAEPgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsDppPolFvAEPgType, make([]TagAnnotationFvRsDppPolFvAEPgResourceModel, 0)) tagTagFvRsDppPolFvAEPgValue, _ := types.SetValueFrom(ctx, TagTagFvRsDppPolFvAEPgType, make([]TagTagFvRsDppPolFvAEPgResourceModel, 0)) annotationValue := planData.Annotation - if stateData != nil { + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.FvRsDppPol.Attributes()) { stateData.FvRsDppPol.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) annotationValue = newAttributeValues.Annotation tagAnnotationFvRsDppPolFvAEPgValue = newAttributeValues.TagAnnotation @@ -3068,37 +3371,13 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan } FvRsDppPolObject, _ := types.ObjectValueFrom(ctx, FvRsDppPolFvAEPgType, FvRsDppPol) planData.FvRsDppPol = FvRsDppPolObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsDppPol = stateData.DeprecatedFvRsDppPol } - if !configData.FvRsFcPathAtt.IsNull() && stateData != nil { - var attributeValues []FvRsFcPathAttFvAEPgResourceModel - var newAttributeValues, stateAttributeValues []string - configData.FvRsFcPathAtt.ElementsAs(ctx, &attributeValues, false) - stateData.DeprecatedFvRsFcPathAtt.ElementsAs(ctx, &stateAttributeValues, false) - for _, attributeValue := range attributeValues { - newAttributeValues = append(newAttributeValues, attributeValue.TDn.ValueString()) - } - - if len(newAttributeValues) == len(stateAttributeValues) { - allMatchState := true - for _, stateAttributeValue := range stateAttributeValues { - if !ContainsString(newAttributeValues, GetMOName(stateAttributeValue)) { - allMatchState = false - break - } - } - if allMatchState { - FvRsFcPathAttSet, _ := types.SetValueFrom(ctx, basetypes.StringType{}, stateAttributeValues) - planData.DeprecatedFvRsFcPathAtt = FvRsFcPathAttSet - } - } - } else if !configData.DeprecatedFvRsFcPathAtt.IsNull() { + if !configData.DeprecatedFvRsFcPathAtt.IsNull() { FvRsFcPathAttList := make([]FvRsFcPathAttFvAEPgResourceModel, 0) var attributeValues []basetypes.StringValue var newAttributeValues []FvRsFcPathAttFvAEPgResourceModel - configData.DeprecatedFvRsFcPathAtt.ElementsAs(ctx, &attributeValues, false) + planData.DeprecatedFvRsFcPathAtt.ElementsAs(ctx, &attributeValues, false) if stateData != nil { stateData.FvRsFcPathAtt.ElementsAs(ctx, &newAttributeValues, false) } @@ -3127,8 +3406,9 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan FvRsFcPathAtt.VsanMode = FvRsFcPathAttValue.VsanMode } else { FvRsFcPathAtt.Annotation = planData.Annotation - FvRsFcPathAtt.Vsan = basetypes.NewStringValue("unknown") // Default to default value from meta when not found - FvRsFcPathAtt.VsanMode = basetypes.NewStringValue("regular") // Default to default value from meta when not found + FvRsFcPathAtt.Descr = basetypes.NewStringUnknown() + FvRsFcPathAtt.Vsan = basetypes.NewStringUnknown() + FvRsFcPathAtt.VsanMode = basetypes.NewStringUnknown() } tagAnnotationFvRsFcPathAttFvAEPgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsFcPathAttFvAEPgType, make([]TagAnnotationFvRsFcPathAttFvAEPgResourceModel, 0)) FvRsFcPathAtt.TagAnnotation = tagAnnotationFvRsFcPathAttFvAEPgValue @@ -3138,37 +3418,13 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan } FvRsFcPathAttSet, _ := types.SetValueFrom(ctx, FvRsFcPathAttFvAEPgType, FvRsFcPathAttList) planData.FvRsFcPathAtt = FvRsFcPathAttSet - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsFcPathAtt = stateData.DeprecatedFvRsFcPathAtt } - if !configData.FvRsConsIf.IsNull() && stateData != nil { - var attributeValues []FvRsConsIfFvAEPgResourceModel - var newAttributeValues, stateAttributeValues []string - configData.FvRsConsIf.ElementsAs(ctx, &attributeValues, false) - stateData.DeprecatedFvRsConsIf.ElementsAs(ctx, &stateAttributeValues, false) - for _, attributeValue := range attributeValues { - newAttributeValues = append(newAttributeValues, attributeValue.TnVzCPIfName.ValueString()) - } - - if len(newAttributeValues) == len(stateAttributeValues) { - allMatchState := true - for _, stateAttributeValue := range stateAttributeValues { - if !ContainsString(newAttributeValues, GetMOName(stateAttributeValue)) { - allMatchState = false - break - } - } - if allMatchState { - FvRsConsIfSet, _ := types.SetValueFrom(ctx, basetypes.StringType{}, stateAttributeValues) - planData.DeprecatedFvRsConsIf = FvRsConsIfSet - } - } - } else if !configData.DeprecatedFvRsConsIf.IsNull() { + if !configData.DeprecatedFvRsConsIf.IsNull() { FvRsConsIfList := make([]FvRsConsIfFvAEPgResourceModel, 0) var attributeValues []basetypes.StringValue var newAttributeValues []FvRsConsIfFvAEPgResourceModel - configData.DeprecatedFvRsConsIf.ElementsAs(ctx, &attributeValues, false) + planData.DeprecatedFvRsConsIf.ElementsAs(ctx, &attributeValues, false) if stateData != nil { stateData.FvRsConsIf.ElementsAs(ctx, &newAttributeValues, false) } @@ -3195,7 +3451,7 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan FvRsConsIf.Prio = FvRsConsIfValue.Prio } else { FvRsConsIf.Annotation = planData.Annotation - FvRsConsIf.Prio = customTypes.NewFvRsConsIfPrioStringValue("unspecified") // Default to default value from meta when not found + FvRsConsIf.Prio = customTypes.NewFvRsConsIfPrioStringUnknown() } tagAnnotationFvRsConsIfFvAEPgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsConsIfFvAEPgType, make([]TagAnnotationFvRsConsIfFvAEPgResourceModel, 0)) FvRsConsIf.TagAnnotation = tagAnnotationFvRsConsIfFvAEPgValue @@ -3205,37 +3461,13 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan } FvRsConsIfSet, _ := types.SetValueFrom(ctx, FvRsConsIfFvAEPgType, FvRsConsIfList) planData.FvRsConsIf = FvRsConsIfSet - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsConsIf = stateData.DeprecatedFvRsConsIf } - if !configData.FvRsIntraEpg.IsNull() && stateData != nil { - var attributeValues []FvRsIntraEpgFvAEPgResourceModel - var newAttributeValues, stateAttributeValues []string - configData.FvRsIntraEpg.ElementsAs(ctx, &attributeValues, false) - stateData.DeprecatedFvRsIntraEpg.ElementsAs(ctx, &stateAttributeValues, false) - for _, attributeValue := range attributeValues { - newAttributeValues = append(newAttributeValues, attributeValue.TnVzBrCPName.ValueString()) - } - - if len(newAttributeValues) == len(stateAttributeValues) { - allMatchState := true - for _, stateAttributeValue := range stateAttributeValues { - if !ContainsString(newAttributeValues, GetMOName(stateAttributeValue)) { - allMatchState = false - break - } - } - if allMatchState { - FvRsIntraEpgSet, _ := types.SetValueFrom(ctx, basetypes.StringType{}, stateAttributeValues) - planData.DeprecatedFvRsIntraEpg = FvRsIntraEpgSet - } - } - } else if !configData.DeprecatedFvRsIntraEpg.IsNull() { + if !configData.DeprecatedFvRsIntraEpg.IsNull() { FvRsIntraEpgList := make([]FvRsIntraEpgFvAEPgResourceModel, 0) var attributeValues []basetypes.StringValue var newAttributeValues []FvRsIntraEpgFvAEPgResourceModel - configData.DeprecatedFvRsIntraEpg.ElementsAs(ctx, &attributeValues, false) + planData.DeprecatedFvRsIntraEpg.ElementsAs(ctx, &attributeValues, false) if stateData != nil { stateData.FvRsIntraEpg.ElementsAs(ctx, &newAttributeValues, false) } @@ -3270,37 +3502,13 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan } FvRsIntraEpgSet, _ := types.SetValueFrom(ctx, FvRsIntraEpgFvAEPgType, FvRsIntraEpgList) planData.FvRsIntraEpg = FvRsIntraEpgSet - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsIntraEpg = stateData.DeprecatedFvRsIntraEpg } - if !configData.FvRsProv.IsNull() && stateData != nil { - var attributeValues []FvRsProvFvAEPgResourceModel - var newAttributeValues, stateAttributeValues []string - configData.FvRsProv.ElementsAs(ctx, &attributeValues, false) - stateData.DeprecatedFvRsProv.ElementsAs(ctx, &stateAttributeValues, false) - for _, attributeValue := range attributeValues { - newAttributeValues = append(newAttributeValues, attributeValue.TnVzBrCPName.ValueString()) - } - - if len(newAttributeValues) == len(stateAttributeValues) { - allMatchState := true - for _, stateAttributeValue := range stateAttributeValues { - if !ContainsString(newAttributeValues, GetMOName(stateAttributeValue)) { - allMatchState = false - break - } - } - if allMatchState { - FvRsProvSet, _ := types.SetValueFrom(ctx, basetypes.StringType{}, stateAttributeValues) - planData.DeprecatedFvRsProv = FvRsProvSet - } - } - } else if !configData.DeprecatedFvRsProv.IsNull() { + if !configData.DeprecatedFvRsProv.IsNull() { FvRsProvList := make([]FvRsProvFvAEPgResourceModel, 0) var attributeValues []basetypes.StringValue var newAttributeValues []FvRsProvFvAEPgResourceModel - configData.DeprecatedFvRsProv.ElementsAs(ctx, &attributeValues, false) + planData.DeprecatedFvRsProv.ElementsAs(ctx, &attributeValues, false) if stateData != nil { stateData.FvRsProv.ElementsAs(ctx, &newAttributeValues, false) } @@ -3328,8 +3536,8 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan FvRsProv.Prio = FvRsProvValue.Prio } else { FvRsProv.Annotation = planData.Annotation - FvRsProv.MatchT = basetypes.NewStringValue("AtleastOne") // Default to default value from meta when not found - FvRsProv.Prio = customTypes.NewFvRsProvPrioStringValue("unspecified") // Default to default value from meta when not found + FvRsProv.MatchT = basetypes.NewStringUnknown() + FvRsProv.Prio = customTypes.NewFvRsProvPrioStringUnknown() } tagAnnotationFvRsProvFvAEPgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsProvFvAEPgType, make([]TagAnnotationFvRsProvFvAEPgResourceModel, 0)) FvRsProv.TagAnnotation = tagAnnotationFvRsProvFvAEPgValue @@ -3339,109 +3547,13 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan } FvRsProvSet, _ := types.SetValueFrom(ctx, FvRsProvFvAEPgType, FvRsProvList) planData.FvRsProv = FvRsProvSet - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsProv = stateData.DeprecatedFvRsProv } - if !configData.FvRsPathAtt.IsNull() && stateData != nil { - var attributeValues []FvRsPathAttFvAEPgResourceModel - var newAttributeValues, stateAttributeValues []string - configData.FvRsPathAtt.ElementsAs(ctx, &attributeValues, false) - stateData.DeprecatedFvRsPathAtt.ElementsAs(ctx, &stateAttributeValues, false) - for _, attributeValue := range attributeValues { - newAttributeValues = append(newAttributeValues, attributeValue.TDn.ValueString()) - } - - if len(newAttributeValues) == len(stateAttributeValues) { - allMatchState := true - for _, stateAttributeValue := range stateAttributeValues { - if !ContainsString(newAttributeValues, GetMOName(stateAttributeValue)) { - allMatchState = false - break - } - } - if allMatchState { - FvRsPathAttSet, _ := types.SetValueFrom(ctx, basetypes.StringType{}, stateAttributeValues) - planData.DeprecatedFvRsPathAtt = FvRsPathAttSet - } - } - } else if !configData.DeprecatedFvRsPathAtt.IsNull() { - FvRsPathAttList := make([]FvRsPathAttFvAEPgResourceModel, 0) - var attributeValues []basetypes.StringValue - var newAttributeValues []FvRsPathAttFvAEPgResourceModel - configData.DeprecatedFvRsPathAtt.ElementsAs(ctx, &attributeValues, false) - if stateData != nil { - stateData.FvRsPathAtt.ElementsAs(ctx, &newAttributeValues, false) - } - for _, attributeValue := range attributeValues { - FvRsPathAttValue := FvRsPathAttFvAEPgResourceModel{} - foundAttributeValue := false - for _, newAttributeValue := range newAttributeValues { - if newAttributeValue.TDn.ValueString() == attributeValue.ValueString() { - FvRsPathAttValue = newAttributeValue - foundAttributeValue = true - break - } - } - tDnValue := basetypes.NewStringUnknown() - if !attributeValue.IsUnknown() { - tDnValue = basetypes.NewStringValue(attributeValue.ValueString()) - } - FvRsPathAtt := FvRsPathAttFvAEPgResourceModel{ - TDn: tDnValue, - } - - if foundAttributeValue { - FvRsPathAtt.Annotation = FvRsPathAttValue.Annotation - FvRsPathAtt.Descr = FvRsPathAttValue.Descr - FvRsPathAtt.Encap = FvRsPathAttValue.Encap - FvRsPathAtt.InstrImedcy = FvRsPathAttValue.InstrImedcy - FvRsPathAtt.Mode = FvRsPathAttValue.Mode - FvRsPathAtt.PrimaryEncap = FvRsPathAttValue.PrimaryEncap - } else { - FvRsPathAtt.Annotation = planData.Annotation - FvRsPathAtt.InstrImedcy = basetypes.NewStringValue("lazy") // Default to default value from meta when not found - FvRsPathAtt.Mode = basetypes.NewStringValue("regular") // Default to default value from meta when not found - } - tagAnnotationFvRsPathAttFvAEPgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsPathAttFvAEPgType, make([]TagAnnotationFvRsPathAttFvAEPgResourceModel, 0)) - FvRsPathAtt.TagAnnotation = tagAnnotationFvRsPathAttFvAEPgValue - tagTagFvRsPathAttFvAEPgValue, _ := types.SetValueFrom(ctx, TagTagFvRsPathAttFvAEPgType, make([]TagTagFvRsPathAttFvAEPgResourceModel, 0)) - FvRsPathAtt.TagTag = tagTagFvRsPathAttFvAEPgValue - FvRsPathAttList = append(FvRsPathAttList, FvRsPathAtt) - } - FvRsPathAttSet, _ := types.SetValueFrom(ctx, FvRsPathAttFvAEPgType, FvRsPathAttList) - planData.FvRsPathAtt = FvRsPathAttSet - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsPathAtt = stateData.DeprecatedFvRsPathAtt - } - - if !configData.FvRsProtBy.IsNull() && stateData != nil { - var attributeValues []FvRsProtByFvAEPgResourceModel - var newAttributeValues, stateAttributeValues []string - configData.FvRsProtBy.ElementsAs(ctx, &attributeValues, false) - stateData.DeprecatedFvRsProtBy.ElementsAs(ctx, &stateAttributeValues, false) - for _, attributeValue := range attributeValues { - newAttributeValues = append(newAttributeValues, attributeValue.TnVzTabooName.ValueString()) - } - - if len(newAttributeValues) == len(stateAttributeValues) { - allMatchState := true - for _, stateAttributeValue := range stateAttributeValues { - if !ContainsString(newAttributeValues, GetMOName(stateAttributeValue)) { - allMatchState = false - break - } - } - if allMatchState { - FvRsProtBySet, _ := types.SetValueFrom(ctx, basetypes.StringType{}, stateAttributeValues) - planData.DeprecatedFvRsProtBy = FvRsProtBySet - } - } - } else if !configData.DeprecatedFvRsProtBy.IsNull() { + if !configData.DeprecatedFvRsProtBy.IsNull() { FvRsProtByList := make([]FvRsProtByFvAEPgResourceModel, 0) var attributeValues []basetypes.StringValue var newAttributeValues []FvRsProtByFvAEPgResourceModel - configData.DeprecatedFvRsProtBy.ElementsAs(ctx, &attributeValues, false) + planData.DeprecatedFvRsProtBy.ElementsAs(ctx, &attributeValues, false) if stateData != nil { stateData.FvRsProtBy.ElementsAs(ctx, &newAttributeValues, false) } @@ -3476,27 +3588,14 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan } FvRsProtBySet, _ := types.SetValueFrom(ctx, FvRsProtByFvAEPgType, FvRsProtByList) planData.FvRsProtBy = FvRsProtBySet - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsProtBy = stateData.DeprecatedFvRsProtBy } - if !configData.FvRsTrustCtrl.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsTrustCtrl.Attributes()) { - planData.FvRsTrustCtrl = configData.FvRsTrustCtrl - planData.DeprecatedFvRsTrustCtrl = basetypes.NewStringNull() - } else { - var attributeValues FvRsTrustCtrlFvAEPgResourceModel - configData.FvRsTrustCtrl.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsTrustCtrl.ValueString()) == attributeValues.TnFhsTrustCtrlPolName.ValueString() && !attributeValues.TnFhsTrustCtrlPolName.IsNull() { - planData.DeprecatedFvRsTrustCtrl = stateData.DeprecatedFvRsTrustCtrl - } - } - } else if !configData.DeprecatedFvRsTrustCtrl.IsNull() { + if !configData.DeprecatedFvRsTrustCtrl.IsNull() { var newAttributeValues FvRsTrustCtrlFvAEPgResourceModel tagAnnotationFvRsTrustCtrlFvAEPgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsTrustCtrlFvAEPgType, make([]TagAnnotationFvRsTrustCtrlFvAEPgResourceModel, 0)) tagTagFvRsTrustCtrlFvAEPgValue, _ := types.SetValueFrom(ctx, TagTagFvRsTrustCtrlFvAEPgType, make([]TagTagFvRsTrustCtrlFvAEPgResourceModel, 0)) annotationValue := planData.Annotation - if stateData != nil { + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.FvRsTrustCtrl.Attributes()) { stateData.FvRsTrustCtrl.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) annotationValue = newAttributeValues.Annotation tagAnnotationFvRsTrustCtrlFvAEPgValue = newAttributeValues.TagAnnotation @@ -3514,36 +3613,52 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan } FvRsTrustCtrlObject, _ := types.ObjectValueFrom(ctx, FvRsTrustCtrlFvAEPgType, FvRsTrustCtrl) planData.FvRsTrustCtrl = FvRsTrustCtrlObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsTrustCtrl = stateData.DeprecatedFvRsTrustCtrl } - planData.DeprecatedFvRsNodeAtt = types.SetNull(deprecatedFvRsNodeAttType) if !configData.DeprecatedFvRsNodeAtt.IsNull() { FvRsNodeAttList := make([]FvRsNodeAttFvAEPgResourceModel, 0) var attributeValues []FvRsNodeAttFvAEPgResourceModelV1 var newAttributeValues []FvRsNodeAttFvAEPgResourceModel - configData.DeprecatedFvRsNodeAtt.ElementsAs(ctx, &attributeValues, false) - annotationValue := planData.Annotation if stateData != nil { stateData.FvRsNodeAtt.ElementsAs(ctx, &newAttributeValues, false) - for _, newAttributeValue := range newAttributeValues { - annotationValue = newAttributeValue.Annotation - } } + planData.DeprecatedFvRsNodeAtt.ElementsAs(ctx, &attributeValues, false) for _, attributeValue := range attributeValues { + plannedFvRsNodeAtt := FvRsNodeAttFvAEPgResourceModel{} + foundAttributeValue := false + for _, newAttributeValue := range newAttributeValues { + if newAttributeValue.TDn.ValueString() == attributeValue.TDn.ValueString() { + plannedFvRsNodeAtt = newAttributeValue + foundAttributeValue = true + break + } + } tDnValue := basetypes.NewStringUnknown() if !attributeValue.TDn.IsUnknown() { tDnValue = basetypes.NewStringValue(attributeValue.TDn.ValueString()) } - FvRsNodeAtt := FvRsNodeAttFvAEPgResourceModel{ - Annotation: annotationValue, - Descr: attributeValue.Descr, - Encap: attributeValue.Encap, - InstrImedcy: attributeValue.InstrImedcy, - Mode: attributeValue.Mode, - TDn: tDnValue, + Annotation: planData.Annotation, + Encap: attributeValue.Encap, + TDn: tDnValue, + } + if !attributeValue.Descr.IsNull() { + FvRsNodeAtt.Descr = attributeValue.Descr + } else { + FvRsNodeAtt.Descr = basetypes.NewStringUnknown() + } + if !attributeValue.InstrImedcy.IsNull() { + FvRsNodeAtt.InstrImedcy = attributeValue.InstrImedcy + } else { + FvRsNodeAtt.InstrImedcy = basetypes.NewStringUnknown() + } + if !attributeValue.Mode.IsNull() { + FvRsNodeAtt.Mode = attributeValue.Mode + } else { + FvRsNodeAtt.Mode = basetypes.NewStringUnknown() + } + if foundAttributeValue { + FvRsNodeAtt.Annotation = plannedFvRsNodeAtt.Annotation } tagAnnotationFvRsNodeAttFvAEPgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsNodeAttFvAEPgType, make([]TagAnnotationFvRsNodeAttFvAEPgResourceModel, 0)) FvRsNodeAtt.TagAnnotation = tagAnnotationFvRsNodeAttFvAEPgValue @@ -3551,14 +3666,192 @@ func (r *FvAEPgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan FvRsNodeAtt.TagTag = tagTagFvRsNodeAttFvAEPgValue FvRsNodeAttList = append(FvRsNodeAttList, FvRsNodeAtt) } - FvRsNodeAttSet, _ := types.SetValueFrom(ctx, FvRsNodeAttFvAEPgType, FvRsNodeAttList) planData.FvRsNodeAtt = FvRsNodeAttSet + } else if !configData.FvRsNodeAtt.IsNull() && stateData == nil { + setUnknownDeprecatedFvRsNodeAttFvAEPgResourceModelToPlan(ctx, planData) + } + + // Workaround to compare the state with plan to avoid plan changes with only known after apply + if stateData != nil { + avoidFvAEPgPlanChangeForKnownAfterApplyOnly(ctx, planData, stateData, configData) } resp.Diagnostics.Append(resp.Plan.Set(ctx, &planData)...) } } +func setUnknownDeprecatedFvRsNodeAttFvAEPgResourceModelToPlan(ctx context.Context, planData *FvAEPgResourceModel) { + var attributeValues []FvRsNodeAttFvAEPgResourceModel + var legacyAttributeValues []FvRsNodeAttFvAEPgResourceModelV1 + planData.FvRsNodeAtt.ElementsAs(ctx, &attributeValues, false) + for i := 0; i < len(attributeValues); i++ { + legacyAttributeValues = append(legacyAttributeValues, FvRsNodeAttFvAEPgResourceModelV1{ + InstrImedcy: basetypes.NewStringUnknown(), + Descr: basetypes.NewStringUnknown(), + Encap: basetypes.NewStringUnknown(), + Mode: basetypes.NewStringUnknown(), + TDn: basetypes.NewStringUnknown(), + }) + } + DeprecatedFvRsNodeAttSet, _ := types.SetValueFrom(ctx, deprecatedFvRsNodeAttType, legacyAttributeValues) + planData.DeprecatedFvRsNodeAtt = DeprecatedFvRsNodeAttSet +} + +func avoidFvAEPgPlanChangeForKnownAfterApplyOnly(ctx context.Context, planData, stateData, configData *FvAEPgResourceModel) { + // Set read-only and deprecated attributes in planData from stateData + planData.PcTag = stateData.PcTag + planData.Scope = stateData.Scope + if configData.DeprecatedExceptionTag.IsNull() { + planData.DeprecatedExceptionTag = stateData.DeprecatedExceptionTag + } + if configData.DeprecatedFloodOnEncap.IsNull() { + planData.DeprecatedFloodOnEncap = stateData.DeprecatedFloodOnEncap + } + if configData.DeprecatedFwdCtrl.IsNull() { + planData.DeprecatedFwdCtrl = stateData.DeprecatedFwdCtrl + } + if configData.DeprecatedHasMcastSource.IsNull() { + planData.DeprecatedHasMcastSource = stateData.DeprecatedHasMcastSource + } + if configData.DeprecatedIsAttrBasedEPg.IsNull() { + planData.DeprecatedIsAttrBasedEPg = stateData.DeprecatedIsAttrBasedEPg + } + if configData.DeprecatedMatchT.IsNull() { + planData.DeprecatedMatchT = stateData.DeprecatedMatchT + } + if configData.DeprecatedParentDn.IsNull() { + planData.DeprecatedParentDn = stateData.DeprecatedParentDn + } + if configData.DeprecatedPcEnfPref.IsNull() { + planData.DeprecatedPcEnfPref = stateData.DeprecatedPcEnfPref + } + if configData.DeprecatedPrefGrMemb.IsNull() { + planData.DeprecatedPrefGrMemb = stateData.DeprecatedPrefGrMemb + } + if configData.DeprecatedPrio.IsNull() { + planData.DeprecatedPrio = stateData.DeprecatedPrio + } + if configData.DeprecatedShutdown.IsNull() { + planData.DeprecatedShutdown = stateData.DeprecatedShutdown + } + if configData.DeprecatedFvRsAEPgMonPol.IsNull() { + planData.DeprecatedFvRsAEPgMonPol = stateData.DeprecatedFvRsAEPgMonPol + } + if configData.DeprecatedFvRsBd.IsNull() { + planData.DeprecatedFvRsBd = stateData.DeprecatedFvRsBd + } + if configData.DeprecatedFvRsCons.IsNull() { + planData.DeprecatedFvRsCons = stateData.DeprecatedFvRsCons + } + if configData.DeprecatedFvRsSecInherited.IsNull() { + planData.DeprecatedFvRsSecInherited = stateData.DeprecatedFvRsSecInherited + } + if configData.DeprecatedFvRsCustQosPol.IsNull() { + planData.DeprecatedFvRsCustQosPol = stateData.DeprecatedFvRsCustQosPol + } + if configData.DeprecatedFvRsDppPol.IsNull() { + planData.DeprecatedFvRsDppPol = stateData.DeprecatedFvRsDppPol + } + if configData.DeprecatedFvRsFcPathAtt.IsNull() { + planData.DeprecatedFvRsFcPathAtt = stateData.DeprecatedFvRsFcPathAtt + } + if configData.DeprecatedFvRsConsIf.IsNull() { + planData.DeprecatedFvRsConsIf = stateData.DeprecatedFvRsConsIf + } + if configData.DeprecatedFvRsIntraEpg.IsNull() { + planData.DeprecatedFvRsIntraEpg = stateData.DeprecatedFvRsIntraEpg + } + if configData.DeprecatedFvRsProv.IsNull() { + planData.DeprecatedFvRsProv = stateData.DeprecatedFvRsProv + } + if configData.DeprecatedFvRsProtBy.IsNull() { + planData.DeprecatedFvRsProtBy = stateData.DeprecatedFvRsProtBy + } + if configData.DeprecatedFvRsTrustCtrl.IsNull() { + planData.DeprecatedFvRsTrustCtrl = stateData.DeprecatedFvRsTrustCtrl + } + if configData.DeprecatedFvRsNodeAtt.IsNull() { + planData.DeprecatedFvRsNodeAtt = stateData.DeprecatedFvRsNodeAtt + } + + // Compare the string representation of the planData and stateData because structs cannot be compared directly + if fmt.Sprintf("%s", planData) != fmt.Sprintf("%s", stateData) { + planData.PcTag = basetypes.NewStringUnknown() + planData.Scope = basetypes.NewStringUnknown() + if configData.DeprecatedExceptionTag.IsNull() { + planData.DeprecatedExceptionTag = basetypes.NewStringUnknown() + } + if configData.DeprecatedFloodOnEncap.IsNull() { + planData.DeprecatedFloodOnEncap = basetypes.NewStringUnknown() + } + if configData.DeprecatedFwdCtrl.IsNull() { + planData.DeprecatedFwdCtrl = basetypes.NewStringUnknown() + } + if configData.DeprecatedHasMcastSource.IsNull() { + planData.DeprecatedHasMcastSource = basetypes.NewStringUnknown() + } + if configData.DeprecatedIsAttrBasedEPg.IsNull() { + planData.DeprecatedIsAttrBasedEPg = basetypes.NewStringUnknown() + } + if configData.DeprecatedMatchT.IsNull() { + planData.DeprecatedMatchT = basetypes.NewStringUnknown() + } + if configData.DeprecatedParentDn.IsNull() { + planData.DeprecatedParentDn = basetypes.NewStringUnknown() + } + if configData.DeprecatedPcEnfPref.IsNull() { + planData.DeprecatedPcEnfPref = basetypes.NewStringUnknown() + } + if configData.DeprecatedPrefGrMemb.IsNull() { + planData.DeprecatedPrefGrMemb = basetypes.NewStringUnknown() + } + if configData.DeprecatedPrio.IsNull() { + planData.DeprecatedPrio = basetypes.NewStringUnknown() + } + if configData.DeprecatedShutdown.IsNull() { + planData.DeprecatedShutdown = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsAEPgMonPol.IsNull() { + planData.DeprecatedFvRsAEPgMonPol = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsBd.IsNull() { + planData.DeprecatedFvRsBd = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsCons.IsNull() { + planData.DeprecatedFvRsCons = basetypes.NewSetUnknown(basetypes.StringType{}) + } + if configData.DeprecatedFvRsSecInherited.IsNull() { + planData.DeprecatedFvRsSecInherited = basetypes.NewSetUnknown(basetypes.StringType{}) + } + if configData.DeprecatedFvRsCustQosPol.IsNull() { + planData.DeprecatedFvRsCustQosPol = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsDppPol.IsNull() { + planData.DeprecatedFvRsDppPol = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsFcPathAtt.IsNull() { + planData.DeprecatedFvRsFcPathAtt = basetypes.NewSetUnknown(basetypes.StringType{}) + } + if configData.DeprecatedFvRsConsIf.IsNull() { + planData.DeprecatedFvRsConsIf = basetypes.NewSetUnknown(basetypes.StringType{}) + } + if configData.DeprecatedFvRsIntraEpg.IsNull() { + planData.DeprecatedFvRsIntraEpg = basetypes.NewSetUnknown(basetypes.StringType{}) + } + if configData.DeprecatedFvRsProv.IsNull() { + planData.DeprecatedFvRsProv = basetypes.NewSetUnknown(basetypes.StringType{}) + } + if configData.DeprecatedFvRsProtBy.IsNull() { + planData.DeprecatedFvRsProtBy = basetypes.NewSetUnknown(basetypes.StringType{}) + } + if configData.DeprecatedFvRsTrustCtrl.IsNull() { + planData.DeprecatedFvRsTrustCtrl = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsNodeAtt.IsNull() { + setUnknownDeprecatedFvRsNodeAttFvAEPgResourceModelToPlan(ctx, planData) + } + } +} func (r *FvAEPgResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { tflog.Debug(ctx, "Start metadata of resource: aci_application_epg") @@ -3685,6 +3978,15 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, }...), }, }, + "relation_fv_rs_path_att": schema.SetAttribute{ + Optional: true, + Computed: true, + ElementType: types.StringType, + DeprecationMessage: "Attribute `relation_fv_rs_path_att` is deprecated. The attribute will be removed in the next major version of the provider.", + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + }, "relation_fv_rs_prov_def": schema.SetAttribute{ Optional: true, Computed: true, @@ -3800,17 +4102,6 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, }...), }, }, - "relation_fv_rs_path_att": schema.SetAttribute{ - Optional: true, - Computed: true, - ElementType: types.StringType, - DeprecationMessage: "Attribute 'relation_fv_rs_path_att' is deprecated, please refer to 'relation_to_static_paths.target_dn' instead. The attribute will be removed in the next major version of the provider.", - Validators: []validator.Set{ - setvalidator.ConflictsWith(path.Expressions{ - path.MatchRoot("relation_to_static_paths"), - }...), - }, - }, "relation_fv_rs_prot_by": schema.SetAttribute{ Optional: true, Computed: true, @@ -3944,12 +4235,16 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, MarkdownDescription: `The provider label match criteria.`, }, "name": schema.StringAttribute{ - Required: true, + Optional: true, + Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, + Validators: []validator.String{ + MakeStringRequired(), + }, MarkdownDescription: `The name of the Application EPG object.`, }, "name_alias": schema.StringAttribute{ @@ -4371,6 +4666,7 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsConsFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -4486,6 +4782,7 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsConsIfFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -4695,6 +4992,7 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsDomAttFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -5125,6 +5423,7 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsFcPathAttFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -5258,6 +5557,7 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsIntraEpgFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -5358,6 +5658,7 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsNodeAttFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -5500,6 +5801,7 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsPathAttFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -5651,6 +5953,7 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsProtByFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -5751,6 +6054,7 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsProvFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -5877,6 +6181,7 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsSecInheritedFvAEPgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -6166,6 +6471,7 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, stringvalidator.ConflictsWith(path.Expressions{ path.MatchRoot("relation_to_static_leafs"), }...), + MakeStringRequired(), }, }, "mode": schema.StringAttribute{ @@ -6186,6 +6492,7 @@ func (r *FvAEPgResource) Schema(ctx context.Context, req resource.SchemaRequest, stringvalidator.ConflictsWith(path.Expressions{ path.MatchRoot("relation_to_static_leafs"), }...), + MakeStringRequired(), }, }, }, diff --git a/internal/provider/resource_aci_application_epg_test.go b/internal/provider/resource_aci_application_epg_test.go index 3c510fc01..c3c756100 100644 --- a/internal/provider/resource_aci_application_epg_test.go +++ b/internal/provider/resource_aci_application_epg_test.go @@ -261,9 +261,9 @@ func TestAccResourceFvAEPgWithFvAp(t *testing.T) { resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_consumed_contracts.1.contract_name", "contract_name_1"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_consumed_contracts.1.priority", "level2"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.0.target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_2"), + resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.0.target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_0"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.1.target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_3"), + resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.1.target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_1"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_custom_qos_policy.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_custom_qos_policy.custom_qos_policy_name", "custom_qos_policy_name_1"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_data_plane_policing_policy.annotation", "annotation_1"), @@ -487,7 +487,7 @@ func TestAccResourceFvAEPgWithFvAp(t *testing.T) { resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.0.tags.1.key", "key_1"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.0.tags.1.value", "test_value"), resource.TestCheckResourceAttr("aci_application_epg.test", "tags.#", "2"), - resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.0.target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_2"), + resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.0.target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_0"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.1.annotation", "annotation_2"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.1.annotations.0.key", "key_0"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.1.annotations.0.value", "value_1"), @@ -499,7 +499,7 @@ func TestAccResourceFvAEPgWithFvAp(t *testing.T) { resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.1.tags.1.key", "key_1"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.1.tags.1.value", "test_value"), resource.TestCheckResourceAttr("aci_application_epg.test", "tags.#", "2"), - resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.1.target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_3"), + resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.1.target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_1"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.#", "2"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_custom_qos_policy.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_custom_qos_policy.annotations.0.key", "key_0"), @@ -853,7 +853,7 @@ func TestAccResourceFvAEPgWithFvAp(t *testing.T) { resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.0.tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.0.tags.0.value", "test_value"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.0.tags.#", "1"), - resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.0.target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_3"), + resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.0.target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_1"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_contract_masters.#", "1"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_custom_qos_policy.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_application_epg.test", "relation_to_custom_qos_policy.annotations.0.key", "key_1"), @@ -1121,19 +1121,80 @@ func TestAccResourceFvAEPgWithFvAp(t *testing.T) { resource.TestCheckResourceAttr("aci_application_epg.test", "priority", "1"), ), }, + // Update with legacy attribute config + { + Config: testConfigFvAEPgLegacyAttributesWithFvAp + testConfigDataSourceSystem, + ExpectNonEmptyPlan: false, + }, + }, + CheckDestroy: testCheckResourceDestroy, + }) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t, "apic", "1.0(1e)-") }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create with legacy attribute config + { + Config: testConfigFvAEPgLegacyAttributesWithFvAp + testConfigDataSourceSystem, + ExpectNonEmptyPlan: false, + }, }, CheckDestroy: testCheckResourceDestroy, }) } const testChildDependencyConfigFvAEPg = ` +resource "aci_monitoring_policy" "test_monitoring_policy_0"{ + tenant_dn = aci_tenant.test.id + name = "monitoring_policy_name_1" +} +resource "aci_bridge_domain" "test_bridge_domain_1"{ + parent_dn = aci_tenant.test.id + name = "bridge_domain_name_1" +} +resource "aci_contract" "test_contract_0"{ + tenant_dn = aci_tenant.test.id + name = "contract_name_0" +} +resource "aci_contract" "test_contract_1"{ + tenant_dn = aci_tenant.test.id + name = "contract_name_1" +} +resource "aci_imported_contract" "test_imported_contract_0"{ + tenant_dn = aci_tenant.test.id + name = "imported_contract_name_0" +} +resource "aci_imported_contract" "test_imported_contract_1"{ + tenant_dn = aci_tenant.test.id + name = "imported_contract_name_1" +} +resource "aci_custom_qos_policy" "test_custom_qos_policy_0"{ + parent_dn = aci_tenant.test.id + name = "custom_qos_policy_name_1" +} +resource "aci_data_plane_policing_policy" "test_data_plane_policing_policy_1"{ + parent_dn = aci_tenant.test.id + name = "data_plane_policing_policy_name_1" +} +resource "aci_taboo_contract" "test_taboo_contract_0"{ + tenant_dn = aci_tenant.test.id + name = "taboo_contract_name_0" +} +resource "aci_taboo_contract" "test_taboo_contract_1"{ + tenant_dn = aci_tenant.test.id + name = "taboo_contract_name_1" +} resource "aci_application_epg" "test_application_epg_0"{ application_profile_dn = aci_application_profile.test.id - name = "epg_2" + name = "epg_0" } resource "aci_application_epg" "test_application_epg_1"{ application_profile_dn = aci_application_profile.test.id - name = "epg_3" + name = "epg_1" +} +resource "aci_trust_control_policy" "test_trust_control_policy_0"{ + parent_dn = aci_tenant.test.id + name = "trust_control_policy_name_1" } ` @@ -1262,11 +1323,11 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - monitoring_policy_name = "monitoring_policy_name_1" + monitoring_policy_name = aci_monitoring_policy.test_monitoring_policy_0.name } relation_to_bridge_domain = { annotation = "annotation_1" - bridge_domain_name = "bridge_domain_name_1" + bridge_domain_name = aci_bridge_domain.test_bridge_domain_1.name annotations = [ { key = "key_0" @@ -1311,7 +1372,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - contract_name = "contract_name_0" + contract_name = aci_contract.test_contract_0.name priority = "level1" }, { @@ -1336,7 +1397,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - contract_name = "contract_name_1" + contract_name = aci_contract.test_contract_1.name priority = "level2" }, ] @@ -1412,7 +1473,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - custom_qos_policy_name = "custom_qos_policy_name_1" + custom_qos_policy_name = aci_custom_qos_policy.test_custom_qos_policy_0.name } relation_to_data_plane_policing_policy = { annotation = "annotation_1" @@ -1436,7 +1497,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - data_plane_policing_policy_name = "data_plane_policing_policy_name_1" + data_plane_policing_policy_name = aci_data_plane_policing_policy.test_data_plane_policing_policy_1.name } relation_to_domains = [ { @@ -1607,7 +1668,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - imported_contract_name = "imported_contract_name_0" + imported_contract_name = aci_imported_contract.test_imported_contract_0.name priority = "level1" }, { @@ -1632,7 +1693,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - imported_contract_name = "imported_contract_name_1" + imported_contract_name = aci_imported_contract.test_imported_contract_1.name priority = "level2" }, ] @@ -1659,7 +1720,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - contract_name = "contract_name_0" + contract_name = aci_contract.test_contract_0.name }, { annotation = "annotation_2" @@ -1683,7 +1744,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - contract_name = "contract_name_1" + contract_name = aci_contract.test_contract_1.name }, ] relation_to_provided_contracts = [ @@ -1709,7 +1770,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - contract_name = "contract_name_0" + contract_name = aci_contract.test_contract_0.name match_criteria = "All" priority = "level1" }, @@ -1735,7 +1796,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - contract_name = "contract_name_1" + contract_name = aci_contract.test_contract_1.name match_criteria = "AtleastOne" priority = "level2" }, @@ -1881,7 +1942,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - taboo_contract_name = "taboo_contract_name_0" + taboo_contract_name = aci_taboo_contract.test_taboo_contract_0.name }, { annotation = "annotation_2" @@ -1905,7 +1966,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - taboo_contract_name = "taboo_contract_name_1" + taboo_contract_name = aci_taboo_contract.test_taboo_contract_1.name }, ] relation_to_trust_control_policy = { @@ -1930,7 +1991,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - trust_control_policy_name = "trust_control_policy_name_1" + trust_control_policy_name = aci_trust_control_policy.test_trust_control_policy_0.name } tags = [ { @@ -1966,7 +2027,7 @@ resource "aci_application_epg" "test" { relation_to_application_epg_monitoring_policy = {} relation_to_bridge_domain = { annotation = "annotation_1" - bridge_domain_name = "bridge_domain_name_1" + bridge_domain_name = aci_bridge_domain.test_bridge_domain_1.name annotations = [ { key = "key_1" @@ -1995,7 +2056,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - contract_name = "contract_name_1" + contract_name = aci_contract.test_contract_1.name priority = "level2" }, ] @@ -2031,7 +2092,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - custom_qos_policy_name = "custom_qos_policy_name_1" + custom_qos_policy_name = aci_custom_qos_policy.test_custom_qos_policy_0.name } relation_to_data_plane_policing_policy = {} relation_to_domains = [ @@ -2108,7 +2169,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - imported_contract_name = "imported_contract_name_1" + imported_contract_name = aci_imported_contract.test_imported_contract_1.name priority = "level2" }, ] @@ -2127,7 +2188,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - contract_name = "contract_name_1" + contract_name = aci_contract.test_contract_1.name }, ] relation_to_provided_contracts = [ @@ -2145,7 +2206,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - contract_name = "contract_name_1" + contract_name = aci_contract.test_contract_1.name match_criteria = "AtleastOne" priority = "level2" }, @@ -2210,7 +2271,7 @@ resource "aci_application_epg" "test" { value = "test_value" }, ] - taboo_contract_name = "taboo_contract_name_1" + taboo_contract_name = aci_taboo_contract.test_taboo_contract_1.name }, ] relation_to_trust_control_policy = {} @@ -2232,7 +2293,7 @@ resource "aci_application_epg" "test" { relation_to_application_epg_monitoring_policy = {} relation_to_bridge_domain = { annotation = "annotation_1" - bridge_domain_name = "bridge_domain_name_1" + bridge_domain_name = aci_bridge_domain.test_bridge_domain_1.name annotations = [] tags = [] } @@ -2242,7 +2303,7 @@ resource "aci_application_epg" "test" { annotation = "annotation_1" annotations = [] tags = [] - custom_qos_policy_name = "custom_qos_policy_name_1" + custom_qos_policy_name = aci_custom_qos_policy.test_custom_qos_policy_0.name } relation_to_data_plane_policing_policy = {} relation_to_domains = [] @@ -2258,10 +2319,45 @@ resource "aci_application_epg" "test" { } ` -const testConfigFvAEPgCustomTypeDependencyWithFvAp = testConfigFvApMinDependencyWithFvTenant + ` +const testConfigFvAEPgCustomTypeDependencyWithFvAp = testChildDependencyConfigFvAEPg + testConfigFvApMinDependencyWithFvTenant + ` resource "aci_application_epg" "test" { parent_dn = aci_application_profile.test.id name = "test_name" priority = "1" } ` +const testConfigFvAEPgLegacyAttributesWithFvAp = testChildDependencyConfigFvAEPg + testConfigFvApMinDependencyWithFvTenant + ` +resource "aci_application_epg" "test" { + name = "test_name" + application_profile_dn = aci_application_profile.test.id + exception_tag = "contract_exception_tag_1" + flood_on_encap = "disabled" + fwd_ctrl = "none" + has_mcast_source = "no" + is_attr_based_epg = "no" + match_t = "All" + pc_enf_pref = "enforced" + pref_gr_memb = "exclude" + prio = "level1" + relation_fv_rs_aepg_mon_pol = aci_monitoring_policy.test_monitoring_policy_0.id + relation_fv_rs_bd = aci_bridge_domain.test_bridge_domain_1.id + relation_fv_rs_cons = [aci_contract.test_contract_1.id] + relation_fv_rs_cons_if = [aci_imported_contract.test_imported_contract_1.id] + relation_fv_rs_cust_qos_pol = aci_custom_qos_policy.test_custom_qos_policy_0.id + relation_fv_rs_dpp_pol = aci_data_plane_policing_policy.test_data_plane_policing_policy_1.id + relation_fv_rs_fc_path_att = ["topology/pod-1/paths-101/pathep-[eth1/1]"] + relation_fv_rs_intra_epg = [aci_contract.test_contract_1.id] + relation_fv_rs_prot_by = [aci_taboo_contract.test_taboo_contract_1.id] + relation_fv_rs_prov = [aci_contract.test_contract_1.id] + relation_fv_rs_sec_inherited = [aci_application_epg.test_application_epg_0.id] + relation_fv_rs_trust_ctrl = aci_trust_control_policy.test_trust_control_policy_0.id + shutdown = "no" + relation_fv_rs_node_att { + deployment_immediacy = "immediate" + description = "description_1" + encap = "vlan-101" + mode = "native" + node_dn = "topology/pod-1/node-101" + } +} +` diff --git a/internal/provider/resource_aci_bridge_domain.go b/internal/provider/resource_aci_bridge_domain.go index 451e0c8ca..bede2e5f2 100644 --- a/internal/provider/resource_aci_bridge_domain.go +++ b/internal/provider/resource_aci_bridge_domain.go @@ -44,83 +44,83 @@ type FvBDResource struct { // FvBDResourceModel describes the resource data model. type FvBDResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - OptimizeWanBandwidth types.String `tfsdk:"optimize_wan_bandwidth"` - Annotation types.String `tfsdk:"annotation"` - ArpFlood types.String `tfsdk:"arp_flooding"` - Descr types.String `tfsdk:"description"` - EnableRogueExceptMac types.String `tfsdk:"enable_rogue_exception_mac"` - EpClear types.String `tfsdk:"clear_remote_mac_entries"` - EpMoveDetectMode types.String `tfsdk:"endpoint_move_detection_mode"` - HostBasedRouting types.String `tfsdk:"advertise_host_routes"` - IntersiteBumTrafficAllow types.String `tfsdk:"enable_intersite_bum_traffic"` - IntersiteL2Stretch types.String `tfsdk:"intersite_l2_stretch"` - IpLearning types.String `tfsdk:"ip_learning"` - Ipv6McastAllow types.String `tfsdk:"pim_ipv6"` - LimitIpLearnToSubnets types.String `tfsdk:"limit_ip_learn_to_subnets"` - LlAddr types.String `tfsdk:"link_local_ipv6_address"` - Mac types.String `tfsdk:"custom_mac_address"` - McastARPDrop types.String `tfsdk:"drop_arp_with_multicast_smac"` - McastAllow types.String `tfsdk:"pim"` - MultiDstPktAct types.String `tfsdk:"multi_destination_flooding"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - OwnerKey types.String `tfsdk:"owner_key"` - OwnerTag types.String `tfsdk:"owner_tag"` - PcTag types.String `tfsdk:"pc_tag"` - Scope types.String `tfsdk:"scope"` - Seg types.String `tfsdk:"segment"` - ServiceBdRoutingDisable types.String `tfsdk:"service_bd_routing_disable"` - Type types.String `tfsdk:"bridge_domain_type"` - UnicastRoute types.String `tfsdk:"unicast_routing"` - UnkMacUcastAct types.String `tfsdk:"l2_unknown_unicast_flooding"` - UnkMcastAct types.String `tfsdk:"l3_unknown_multicast_flooding"` - V6unkMcastAct types.String `tfsdk:"ipv6_l3_unknown_multicast_flooding"` - Vmac types.String `tfsdk:"virtual_mac_address"` - FvAccP types.Object `tfsdk:"legacy_mode"` - FvRogueExceptionMac types.Set `tfsdk:"rogue_coop_exceptions"` - FvRsABDPolMonPol types.Object `tfsdk:"relation_to_monitor_policy"` - FvRsBDToFhs types.Object `tfsdk:"relation_to_first_hop_security_policy"` - FvRsBDToNdP types.Object `tfsdk:"relation_to_neighbor_discovery_interface_policy"` - FvRsBDToNetflowMonitorPol types.Set `tfsdk:"relation_to_netflow_monitor_policies"` - FvRsBDToOut types.Set `tfsdk:"relation_to_l3_outsides"` - FvRsBDToProfile types.Object `tfsdk:"relation_to_route_control_profile"` - FvRsBDToRelayP types.Object `tfsdk:"relation_to_dhcp_relay_policy"` - FvRsBdToEpRet types.Object `tfsdk:"relation_to_end_point_retention_policy"` - FvRsCtx types.Object `tfsdk:"relation_to_vrf"` - FvRsIgmpsn types.Object `tfsdk:"relation_to_igmp_snooping_policy"` - FvRsMldsn types.Object `tfsdk:"relation_to_mld_snooping_policy"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` - DeprecatedArpFlood types.String `tfsdk:"arp_flood"` - DeprecatedEpClear types.String `tfsdk:"ep_clear"` - DeprecatedEpMoveDetectMode types.String `tfsdk:"ep_move_detect_mode"` - DeprecatedHostBasedRouting types.String `tfsdk:"host_based_routing"` - DeprecatedIntersiteBumTrafficAllow types.String `tfsdk:"intersite_bum_traffic_allow"` - DeprecatedIpv6McastAllow types.String `tfsdk:"ipv6_mcast_allow"` - DeprecatedLlAddr types.String `tfsdk:"ll_addr"` - DeprecatedMac types.String `tfsdk:"mac"` - DeprecatedMcastAllow types.String `tfsdk:"mcast_allow"` - DeprecatedMultiDstPktAct types.String `tfsdk:"multi_dst_pkt_act"` - DeprecatedParentDn types.String `tfsdk:"tenant_dn"` - DeprecatedUnicastRoute types.String `tfsdk:"unicast_route"` - DeprecatedUnkMacUcastAct types.String `tfsdk:"unk_mac_ucast_act"` - DeprecatedUnkMcastAct types.String `tfsdk:"unk_mcast_act"` - DeprecatedV6unkMcastAct types.String `tfsdk:"v6unk_mcast_act"` - DeprecatedVmac types.String `tfsdk:"vmac"` - Deprecated_relation_fv_rs_bd_flood_to types.Set `tfsdk:"relation_fv_rs_bd_flood_to"` - DeprecatedFvRsBDToRelayP types.String `tfsdk:"relation_fv_rs_bd_to_relay_p"` - DeprecatedFvRsBdToEpRet types.String `tfsdk:"relation_fv_rs_bd_to_ep_ret"` - DeprecatedFvRsBDToFhs types.String `tfsdk:"relation_fv_rs_bd_to_fhs"` - DeprecatedFvRsIgmpsn types.String `tfsdk:"relation_fv_rs_igmpsn"` - DeprecatedFvRsBDToOut types.Set `tfsdk:"relation_fv_rs_bd_to_out"` - DeprecatedFvRsMldsn types.String `tfsdk:"relation_fv_rs_mldsn"` - DeprecatedFvRsABDPolMonPol types.String `tfsdk:"relation_fv_rs_abd_pol_mon_pol"` - DeprecatedFvRsBDToNdP types.String `tfsdk:"relation_fv_rs_bd_to_nd_p"` - DeprecatedFvRsBDToProfile types.String `tfsdk:"relation_fv_rs_bd_to_profile"` - DeprecatedFvRsCtx types.String `tfsdk:"relation_fv_rs_ctx"` - DeprecatedFvRsBDToNetflowMonitorPol types.Set `tfsdk:"relation_fv_rs_bd_to_netflow_monitor_pol"` + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + OptimizeWanBandwidth types.String `tfsdk:"optimize_wan_bandwidth"` + Annotation types.String `tfsdk:"annotation"` + ArpFlood types.String `tfsdk:"arp_flooding"` + Descr types.String `tfsdk:"description"` + EnableRogueExceptMac types.String `tfsdk:"enable_rogue_exception_mac"` + EpClear types.String `tfsdk:"clear_remote_mac_entries"` + EpMoveDetectMode types.String `tfsdk:"endpoint_move_detection_mode"` + HostBasedRouting types.String `tfsdk:"advertise_host_routes"` + IntersiteBumTrafficAllow types.String `tfsdk:"enable_intersite_bum_traffic"` + IntersiteL2Stretch types.String `tfsdk:"intersite_l2_stretch"` + IpLearning types.String `tfsdk:"ip_learning"` + Ipv6McastAllow types.String `tfsdk:"pim_ipv6"` + LimitIpLearnToSubnets types.String `tfsdk:"limit_ip_learn_to_subnets"` + LlAddr types.String `tfsdk:"link_local_ipv6_address"` + Mac types.String `tfsdk:"custom_mac_address"` + McastARPDrop types.String `tfsdk:"drop_arp_with_multicast_smac"` + McastAllow types.String `tfsdk:"pim"` + MultiDstPktAct types.String `tfsdk:"multi_destination_flooding"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + OwnerKey types.String `tfsdk:"owner_key"` + OwnerTag types.String `tfsdk:"owner_tag"` + PcTag types.String `tfsdk:"pc_tag"` + Scope types.String `tfsdk:"scope"` + Seg types.String `tfsdk:"segment"` + ServiceBdRoutingDisable types.String `tfsdk:"service_bd_routing_disable"` + Type types.String `tfsdk:"bridge_domain_type"` + UnicastRoute types.String `tfsdk:"unicast_routing"` + UnkMacUcastAct types.String `tfsdk:"l2_unknown_unicast_flooding"` + UnkMcastAct types.String `tfsdk:"l3_unknown_multicast_flooding"` + V6unkMcastAct types.String `tfsdk:"ipv6_l3_unknown_multicast_flooding"` + Vmac types.String `tfsdk:"virtual_mac_address"` + FvAccP types.Object `tfsdk:"legacy_mode"` + FvRogueExceptionMac types.Set `tfsdk:"rogue_coop_exceptions"` + FvRsABDPolMonPol types.Object `tfsdk:"relation_to_monitor_policy"` + FvRsBDToFhs types.Object `tfsdk:"relation_to_first_hop_security_policy"` + FvRsBDToNdP types.Object `tfsdk:"relation_to_neighbor_discovery_interface_policy"` + FvRsBDToNetflowMonitorPol types.Set `tfsdk:"relation_to_netflow_monitor_policies"` + FvRsBDToOut types.Set `tfsdk:"relation_to_l3_outsides"` + FvRsBDToProfile types.Object `tfsdk:"relation_to_route_control_profile"` + FvRsBDToRelayP types.Object `tfsdk:"relation_to_dhcp_relay_policy"` + FvRsBdToEpRet types.Object `tfsdk:"relation_to_end_point_retention_policy"` + FvRsCtx types.Object `tfsdk:"relation_to_vrf"` + FvRsIgmpsn types.Object `tfsdk:"relation_to_igmp_snooping_policy"` + FvRsMldsn types.Object `tfsdk:"relation_to_mld_snooping_policy"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` + DeprecatedArpFlood types.String `tfsdk:"arp_flood"` + DeprecatedEpClear types.String `tfsdk:"ep_clear"` + DeprecatedEpMoveDetectMode types.String `tfsdk:"ep_move_detect_mode"` + DeprecatedHostBasedRouting types.String `tfsdk:"host_based_routing"` + DeprecatedIntersiteBumTrafficAllow types.String `tfsdk:"intersite_bum_traffic_allow"` + DeprecatedIpv6McastAllow types.String `tfsdk:"ipv6_mcast_allow"` + DeprecatedLlAddr types.String `tfsdk:"ll_addr"` + DeprecatedMac types.String `tfsdk:"mac"` + DeprecatedMcastAllow types.String `tfsdk:"mcast_allow"` + DeprecatedMultiDstPktAct types.String `tfsdk:"multi_dst_pkt_act"` + DeprecatedParentDn types.String `tfsdk:"tenant_dn"` + DeprecatedUnicastRoute types.String `tfsdk:"unicast_route"` + DeprecatedUnkMacUcastAct types.String `tfsdk:"unk_mac_ucast_act"` + DeprecatedUnkMcastAct types.String `tfsdk:"unk_mcast_act"` + DeprecatedV6unkMcastAct types.String `tfsdk:"v6unk_mcast_act"` + DeprecatedVmac types.String `tfsdk:"vmac"` + Deprecated_relation_fv_rs_bd_flood_to types.Set `tfsdk:"relation_fv_rs_bd_flood_to"` + Deprecated_relation_fv_rs_bd_to_profile types.String `tfsdk:"relation_fv_rs_bd_to_profile"` + DeprecatedFvRsBDToRelayP types.String `tfsdk:"relation_fv_rs_bd_to_relay_p"` + DeprecatedFvRsBdToEpRet types.String `tfsdk:"relation_fv_rs_bd_to_ep_ret"` + DeprecatedFvRsBDToFhs types.String `tfsdk:"relation_fv_rs_bd_to_fhs"` + DeprecatedFvRsIgmpsn types.String `tfsdk:"relation_fv_rs_igmpsn"` + DeprecatedFvRsBDToOut types.Set `tfsdk:"relation_fv_rs_bd_to_out"` + DeprecatedFvRsMldsn types.String `tfsdk:"relation_fv_rs_mldsn"` + DeprecatedFvRsABDPolMonPol types.String `tfsdk:"relation_fv_rs_abd_pol_mon_pol"` + DeprecatedFvRsBDToNdP types.String `tfsdk:"relation_fv_rs_bd_to_nd_p"` + DeprecatedFvRsCtx types.String `tfsdk:"relation_fv_rs_ctx"` + DeprecatedFvRsBDToNetflowMonitorPol types.Set `tfsdk:"relation_fv_rs_bd_to_netflow_monitor_pol"` } func getEmptyFvBDResourceModel() *FvBDResourceModel { @@ -266,34 +266,34 @@ func getEmptyFvBDResourceModel() *FvBDResourceModel { "value": types.StringType, }, }), - DeprecatedArpFlood: types.String{}, - DeprecatedEpClear: types.String{}, - DeprecatedEpMoveDetectMode: types.String{}, - DeprecatedHostBasedRouting: types.String{}, - DeprecatedIntersiteBumTrafficAllow: types.String{}, - DeprecatedIpv6McastAllow: types.String{}, - DeprecatedLlAddr: types.String{}, - DeprecatedMac: types.String{}, - DeprecatedMcastAllow: types.String{}, - DeprecatedMultiDstPktAct: types.String{}, - DeprecatedParentDn: types.String{}, - DeprecatedUnicastRoute: types.String{}, - DeprecatedUnkMacUcastAct: types.String{}, - DeprecatedUnkMcastAct: types.String{}, - DeprecatedV6unkMcastAct: types.String{}, - DeprecatedVmac: types.String{}, - Deprecated_relation_fv_rs_bd_flood_to: types.SetNull(types.StringType), - DeprecatedFvRsBDToRelayP: types.String{}, - DeprecatedFvRsBdToEpRet: types.String{}, - DeprecatedFvRsBDToFhs: types.String{}, - DeprecatedFvRsIgmpsn: types.String{}, - DeprecatedFvRsBDToOut: types.SetNull(types.StringType), - DeprecatedFvRsMldsn: types.String{}, - DeprecatedFvRsABDPolMonPol: types.String{}, - DeprecatedFvRsBDToNdP: types.String{}, - DeprecatedFvRsBDToProfile: types.String{}, - DeprecatedFvRsCtx: types.String{}, - DeprecatedFvRsBDToNetflowMonitorPol: types.SetNull(deprecatedFvRsBDToNetflowMonitorPolType), + DeprecatedArpFlood: types.String{}, + DeprecatedEpClear: types.String{}, + DeprecatedEpMoveDetectMode: types.String{}, + DeprecatedHostBasedRouting: types.String{}, + DeprecatedIntersiteBumTrafficAllow: types.String{}, + DeprecatedIpv6McastAllow: types.String{}, + DeprecatedLlAddr: types.String{}, + DeprecatedMac: types.String{}, + DeprecatedMcastAllow: types.String{}, + DeprecatedMultiDstPktAct: types.String{}, + DeprecatedParentDn: types.String{}, + DeprecatedUnicastRoute: types.String{}, + DeprecatedUnkMacUcastAct: types.String{}, + DeprecatedUnkMcastAct: types.String{}, + DeprecatedV6unkMcastAct: types.String{}, + DeprecatedVmac: types.String{}, + Deprecated_relation_fv_rs_bd_flood_to: types.SetNull(types.StringType), + Deprecated_relation_fv_rs_bd_to_profile: types.String{}, + DeprecatedFvRsBDToRelayP: types.String{}, + DeprecatedFvRsBdToEpRet: types.String{}, + DeprecatedFvRsBDToFhs: types.String{}, + DeprecatedFvRsIgmpsn: types.String{}, + DeprecatedFvRsBDToOut: types.SetNull(types.StringType), + DeprecatedFvRsMldsn: types.String{}, + DeprecatedFvRsABDPolMonPol: types.String{}, + DeprecatedFvRsBDToNdP: types.String{}, + DeprecatedFvRsCtx: types.String{}, + DeprecatedFvRsBDToNetflowMonitorPol: types.SetNull(deprecatedFvRsBDToNetflowMonitorPolType), } } @@ -431,6 +431,47 @@ var FvRogueExceptionMacFvBDType = types.ObjectType{ }, } +func FvRogueExceptionMacFvBDSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRogueExceptionMacFvBDResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.Descr.IsNull() { + nullInStateFound = true + planSetValues[index].Descr = basetypes.NewStringNull() + } + if stateValue.Mac.IsNull() { + nullInStateFound = true + planSetValues[index].Mac = basetypes.NewStringNull() + } + if stateValue.Name.IsNull() { + nullInStateFound = true + planSetValues[index].Name = basetypes.NewStringNull() + } + if stateValue.NameAlias.IsNull() { + nullInStateFound = true + planSetValues[index].NameAlias = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRogueExceptionMacFvBDType, planSetValues) + return planSet + +} + // TagAnnotationFvRogueExceptionMacFvBDResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRogueExceptionMacFvBDResourceModel struct { Key types.String `tfsdk:"key"` @@ -732,6 +773,39 @@ var FvRsBDToNetflowMonitorPolFvBDType = types.ObjectType{ }, } +func FvRsBDToNetflowMonitorPolFvBDSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsBDToNetflowMonitorPolFvBDResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.FltType.IsNull() { + nullInStateFound = true + planSetValues[index].FltType = basetypes.NewStringNull() + } + if stateValue.TnNetflowMonitorPolName.IsNull() { + nullInStateFound = true + planSetValues[index].TnNetflowMonitorPolName = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsBDToNetflowMonitorPolFvBDType, planSetValues) + return planSet + +} + // TagAnnotationFvRsBDToNetflowMonitorPolFvBDResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsBDToNetflowMonitorPolFvBDResourceModel struct { Key types.String `tfsdk:"key"` @@ -808,6 +882,35 @@ var FvRsBDToOutFvBDType = types.ObjectType{ }, } +func FvRsBDToOutFvBDSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsBDToOutFvBDResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.TnL3extOutName.IsNull() { + nullInStateFound = true + planSetValues[index].TnL3extOutName = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsBDToOutFvBDType, planSetValues) + return planSet + +} + // TagAnnotationFvRsBDToOutFvBDResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsBDToOutFvBDResourceModel struct { Key types.String `tfsdk:"key"` @@ -1350,44 +1453,44 @@ var deprecatedFvRsBDToNetflowMonitorPolType = types.ObjectType{ } type FvBDResourceModelV1 struct { - Annotation types.String `tfsdk:"annotation"` - ArpFlood types.String `tfsdk:"arp_flood"` - Descr types.String `tfsdk:"description"` - EpClear types.String `tfsdk:"ep_clear"` - EpMoveDetectMode types.String `tfsdk:"ep_move_detect_mode"` - HostBasedRouting types.String `tfsdk:"host_based_routing"` - Id types.String `tfsdk:"id"` - IntersiteBumTrafficAllow types.String `tfsdk:"intersite_bum_traffic_allow"` - IntersiteL2Stretch types.String `tfsdk:"intersite_l2_stretch"` - IpLearning types.String `tfsdk:"ip_learning"` - Ipv6McastAllow types.String `tfsdk:"ipv6_mcast_allow"` - LimitIpLearnToSubnets types.String `tfsdk:"limit_ip_learn_to_subnets"` - LlAddr types.String `tfsdk:"ll_addr"` - Mac types.String `tfsdk:"mac"` - McastAllow types.String `tfsdk:"mcast_allow"` - MultiDstPktAct types.String `tfsdk:"multi_dst_pkt_act"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - OptimizeWanBandwidth types.String `tfsdk:"optimize_wan_bandwidth"` - ParentDn types.String `tfsdk:"tenant_dn"` - Type types.String `tfsdk:"bridge_domain_type"` - UnicastRoute types.String `tfsdk:"unicast_route"` - UnkMacUcastAct types.String `tfsdk:"unk_mac_ucast_act"` - UnkMcastAct types.String `tfsdk:"unk_mcast_act"` - V6unkMcastAct types.String `tfsdk:"v6unk_mcast_act"` - Vmac types.String `tfsdk:"vmac"` - Deprecated_relation_fv_rs_bd_flood_to types.Set `tfsdk:"relation_fv_rs_bd_flood_to"` - FvRsBDToRelayP types.String `tfsdk:"relation_fv_rs_bd_to_relay_p"` - FvRsBdToEpRet types.String `tfsdk:"relation_fv_rs_bd_to_ep_ret"` - FvRsBDToFhs types.String `tfsdk:"relation_fv_rs_bd_to_fhs"` - FvRsIgmpsn types.String `tfsdk:"relation_fv_rs_igmpsn"` - FvRsBDToOut types.Set `tfsdk:"relation_fv_rs_bd_to_out"` - FvRsMldsn types.String `tfsdk:"relation_fv_rs_mldsn"` - FvRsABDPolMonPol types.String `tfsdk:"relation_fv_rs_abd_pol_mon_pol"` - FvRsBDToNdP types.String `tfsdk:"relation_fv_rs_bd_to_nd_p"` - FvRsBDToProfile types.String `tfsdk:"relation_fv_rs_bd_to_profile"` - FvRsCtx types.String `tfsdk:"relation_fv_rs_ctx"` - FvRsBDToNetflowMonitorPol types.Set `tfsdk:"relation_fv_rs_bd_to_netflow_monitor_pol"` + Annotation types.String `tfsdk:"annotation"` + ArpFlood types.String `tfsdk:"arp_flood"` + Descr types.String `tfsdk:"description"` + EpClear types.String `tfsdk:"ep_clear"` + EpMoveDetectMode types.String `tfsdk:"ep_move_detect_mode"` + HostBasedRouting types.String `tfsdk:"host_based_routing"` + Id types.String `tfsdk:"id"` + IntersiteBumTrafficAllow types.String `tfsdk:"intersite_bum_traffic_allow"` + IntersiteL2Stretch types.String `tfsdk:"intersite_l2_stretch"` + IpLearning types.String `tfsdk:"ip_learning"` + Ipv6McastAllow types.String `tfsdk:"ipv6_mcast_allow"` + LimitIpLearnToSubnets types.String `tfsdk:"limit_ip_learn_to_subnets"` + LlAddr types.String `tfsdk:"ll_addr"` + Mac types.String `tfsdk:"mac"` + McastAllow types.String `tfsdk:"mcast_allow"` + MultiDstPktAct types.String `tfsdk:"multi_dst_pkt_act"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + OptimizeWanBandwidth types.String `tfsdk:"optimize_wan_bandwidth"` + ParentDn types.String `tfsdk:"tenant_dn"` + Type types.String `tfsdk:"bridge_domain_type"` + UnicastRoute types.String `tfsdk:"unicast_route"` + UnkMacUcastAct types.String `tfsdk:"unk_mac_ucast_act"` + UnkMcastAct types.String `tfsdk:"unk_mcast_act"` + V6unkMcastAct types.String `tfsdk:"v6unk_mcast_act"` + Vmac types.String `tfsdk:"vmac"` + Deprecated_relation_fv_rs_bd_flood_to types.Set `tfsdk:"relation_fv_rs_bd_flood_to"` + Deprecated_relation_fv_rs_bd_to_profile types.String `tfsdk:"relation_fv_rs_bd_to_profile"` + FvRsBDToRelayP types.String `tfsdk:"relation_fv_rs_bd_to_relay_p"` + FvRsBdToEpRet types.String `tfsdk:"relation_fv_rs_bd_to_ep_ret"` + FvRsBDToFhs types.String `tfsdk:"relation_fv_rs_bd_to_fhs"` + FvRsIgmpsn types.String `tfsdk:"relation_fv_rs_igmpsn"` + FvRsBDToOut types.Set `tfsdk:"relation_fv_rs_bd_to_out"` + FvRsMldsn types.String `tfsdk:"relation_fv_rs_mldsn"` + FvRsABDPolMonPol types.String `tfsdk:"relation_fv_rs_abd_pol_mon_pol"` + FvRsBDToNdP types.String `tfsdk:"relation_fv_rs_bd_to_nd_p"` + FvRsCtx types.String `tfsdk:"relation_fv_rs_ctx"` + FvRsBDToNetflowMonitorPol types.Set `tfsdk:"relation_fv_rs_bd_to_netflow_monitor_pol"` } type FvRsBDToNetflowMonitorPolFvBDResourceModelV1 struct { @@ -1395,6 +1498,13 @@ type FvRsBDToNetflowMonitorPolFvBDResourceModelV1 struct { TnNetflowMonitorPolName types.String `tfsdk:"tn_netflow_monitor_pol_name"` } +func getEmptyFvRsBDToNetflowMonitorPolFvBDResourceModelV1() FvRsBDToNetflowMonitorPolFvBDResourceModelV1 { + return FvRsBDToNetflowMonitorPolFvBDResourceModelV1{ + FltType: basetypes.NewStringNull(), + TnNetflowMonitorPolName: basetypes.NewStringNull(), + } +} + func (r *FvBDResource) UpgradeState(ctx context.Context) map[int64]resource.StateUpgrader { return map[int64]resource.StateUpgrader{ 1: { @@ -1536,6 +1646,11 @@ func (r *FvBDResource) UpgradeState(ctx context.Context) map[int64]resource.Stat Computed: false, ElementType: types.StringType, }, + "relation_fv_rs_bd_to_profile": schema.StringAttribute{ + Required: false, + Optional: true, + Computed: false, + }, "relation_fv_rs_bd_to_relay_p": schema.StringAttribute{ Required: false, Optional: true, @@ -1577,11 +1692,6 @@ func (r *FvBDResource) UpgradeState(ctx context.Context) map[int64]resource.Stat Optional: true, Computed: true, }, - "relation_fv_rs_bd_to_profile": schema.StringAttribute{ - Required: false, - Optional: true, - Computed: false, - }, "relation_fv_rs_ctx": schema.StringAttribute{ Required: false, Optional: true, @@ -1617,66 +1727,66 @@ func (r *FvBDResource) UpgradeState(ctx context.Context) map[int64]resource.Stat } upgradedStateData := FvBDResourceModel{ - Id: priorStateData.Id, - ParentDn: priorStateData.ParentDn, - OptimizeWanBandwidth: priorStateData.OptimizeWanBandwidth, - Annotation: priorStateData.Annotation, - ArpFlood: priorStateData.ArpFlood, - Descr: priorStateData.Descr, - EnableRogueExceptMac: basetypes.NewStringNull(), - EpClear: priorStateData.EpClear, - EpMoveDetectMode: priorStateData.EpMoveDetectMode, - HostBasedRouting: priorStateData.HostBasedRouting, - IntersiteBumTrafficAllow: priorStateData.IntersiteBumTrafficAllow, - IntersiteL2Stretch: priorStateData.IntersiteL2Stretch, - IpLearning: priorStateData.IpLearning, - Ipv6McastAllow: priorStateData.Ipv6McastAllow, - LimitIpLearnToSubnets: priorStateData.LimitIpLearnToSubnets, - LlAddr: priorStateData.LlAddr, - Mac: priorStateData.Mac, - McastARPDrop: basetypes.NewStringNull(), - McastAllow: priorStateData.McastAllow, - MultiDstPktAct: priorStateData.MultiDstPktAct, - Name: priorStateData.Name, - NameAlias: priorStateData.NameAlias, - OwnerKey: basetypes.NewStringNull(), - OwnerTag: basetypes.NewStringNull(), - PcTag: basetypes.NewStringNull(), - Scope: basetypes.NewStringNull(), - Seg: basetypes.NewStringNull(), - ServiceBdRoutingDisable: basetypes.NewStringNull(), - Type: priorStateData.Type, - UnicastRoute: priorStateData.UnicastRoute, - UnkMacUcastAct: priorStateData.UnkMacUcastAct, - UnkMcastAct: priorStateData.UnkMcastAct, - V6unkMcastAct: priorStateData.V6unkMcastAct, - Vmac: priorStateData.Vmac, - DeprecatedArpFlood: priorStateData.ArpFlood, - DeprecatedEpClear: priorStateData.EpClear, - DeprecatedEpMoveDetectMode: priorStateData.EpMoveDetectMode, - DeprecatedHostBasedRouting: priorStateData.HostBasedRouting, - DeprecatedIntersiteBumTrafficAllow: priorStateData.IntersiteBumTrafficAllow, - DeprecatedIpv6McastAllow: priorStateData.Ipv6McastAllow, - DeprecatedLlAddr: priorStateData.LlAddr, - DeprecatedMac: priorStateData.Mac, - DeprecatedMcastAllow: priorStateData.McastAllow, - DeprecatedMultiDstPktAct: priorStateData.MultiDstPktAct, - DeprecatedParentDn: priorStateData.ParentDn, - DeprecatedUnicastRoute: priorStateData.UnicastRoute, - DeprecatedUnkMacUcastAct: priorStateData.UnkMacUcastAct, - DeprecatedUnkMcastAct: priorStateData.UnkMcastAct, - DeprecatedV6unkMcastAct: priorStateData.V6unkMcastAct, - DeprecatedVmac: priorStateData.Vmac, - Deprecated_relation_fv_rs_bd_flood_to: priorStateData.Deprecated_relation_fv_rs_bd_flood_to, - DeprecatedFvRsBDToRelayP: priorStateData.FvRsBDToRelayP, - DeprecatedFvRsBdToEpRet: priorStateData.FvRsBdToEpRet, - DeprecatedFvRsBDToFhs: priorStateData.FvRsBDToFhs, - DeprecatedFvRsIgmpsn: priorStateData.FvRsIgmpsn, - DeprecatedFvRsMldsn: priorStateData.FvRsMldsn, - DeprecatedFvRsABDPolMonPol: priorStateData.FvRsABDPolMonPol, - DeprecatedFvRsBDToNdP: priorStateData.FvRsBDToNdP, - DeprecatedFvRsBDToProfile: priorStateData.FvRsBDToProfile, - DeprecatedFvRsCtx: priorStateData.FvRsCtx, + Id: priorStateData.Id, + ParentDn: priorStateData.ParentDn, + OptimizeWanBandwidth: priorStateData.OptimizeWanBandwidth, + Annotation: priorStateData.Annotation, + ArpFlood: priorStateData.ArpFlood, + Descr: priorStateData.Descr, + EnableRogueExceptMac: basetypes.NewStringNull(), + EpClear: priorStateData.EpClear, + EpMoveDetectMode: priorStateData.EpMoveDetectMode, + HostBasedRouting: priorStateData.HostBasedRouting, + IntersiteBumTrafficAllow: priorStateData.IntersiteBumTrafficAllow, + IntersiteL2Stretch: priorStateData.IntersiteL2Stretch, + IpLearning: priorStateData.IpLearning, + Ipv6McastAllow: priorStateData.Ipv6McastAllow, + LimitIpLearnToSubnets: priorStateData.LimitIpLearnToSubnets, + LlAddr: priorStateData.LlAddr, + Mac: priorStateData.Mac, + McastARPDrop: basetypes.NewStringNull(), + McastAllow: priorStateData.McastAllow, + MultiDstPktAct: priorStateData.MultiDstPktAct, + Name: priorStateData.Name, + NameAlias: priorStateData.NameAlias, + OwnerKey: basetypes.NewStringNull(), + OwnerTag: basetypes.NewStringNull(), + PcTag: basetypes.NewStringNull(), + Scope: basetypes.NewStringNull(), + Seg: basetypes.NewStringNull(), + ServiceBdRoutingDisable: basetypes.NewStringNull(), + Type: priorStateData.Type, + UnicastRoute: priorStateData.UnicastRoute, + UnkMacUcastAct: priorStateData.UnkMacUcastAct, + UnkMcastAct: priorStateData.UnkMcastAct, + V6unkMcastAct: priorStateData.V6unkMcastAct, + Vmac: priorStateData.Vmac, + DeprecatedArpFlood: priorStateData.ArpFlood, + DeprecatedEpClear: priorStateData.EpClear, + DeprecatedEpMoveDetectMode: priorStateData.EpMoveDetectMode, + DeprecatedHostBasedRouting: priorStateData.HostBasedRouting, + DeprecatedIntersiteBumTrafficAllow: priorStateData.IntersiteBumTrafficAllow, + DeprecatedIpv6McastAllow: priorStateData.Ipv6McastAllow, + DeprecatedLlAddr: priorStateData.LlAddr, + DeprecatedMac: priorStateData.Mac, + DeprecatedMcastAllow: priorStateData.McastAllow, + DeprecatedMultiDstPktAct: priorStateData.MultiDstPktAct, + DeprecatedParentDn: priorStateData.ParentDn, + DeprecatedUnicastRoute: priorStateData.UnicastRoute, + DeprecatedUnkMacUcastAct: priorStateData.UnkMacUcastAct, + DeprecatedUnkMcastAct: priorStateData.UnkMcastAct, + DeprecatedV6unkMcastAct: priorStateData.V6unkMcastAct, + DeprecatedVmac: priorStateData.Vmac, + Deprecated_relation_fv_rs_bd_flood_to: priorStateData.Deprecated_relation_fv_rs_bd_flood_to, + Deprecated_relation_fv_rs_bd_to_profile: priorStateData.Deprecated_relation_fv_rs_bd_to_profile, + DeprecatedFvRsBDToRelayP: priorStateData.FvRsBDToRelayP, + DeprecatedFvRsBdToEpRet: priorStateData.FvRsBdToEpRet, + DeprecatedFvRsBDToFhs: priorStateData.FvRsBDToFhs, + DeprecatedFvRsIgmpsn: priorStateData.FvRsIgmpsn, + DeprecatedFvRsMldsn: priorStateData.FvRsMldsn, + DeprecatedFvRsABDPolMonPol: priorStateData.FvRsABDPolMonPol, + DeprecatedFvRsBDToNdP: priorStateData.FvRsBDToNdP, + DeprecatedFvRsCtx: priorStateData.FvRsCtx, } upgradedStateData.FvAccP = types.ObjectNull(FvAccPFvBDType) @@ -1803,25 +1913,7 @@ func (r *FvBDResource) UpgradeState(ctx context.Context) map[int64]resource.Stat FvRsBDToOutSet, _ := types.SetValueFrom(ctx, FvRsBDToOutFvBDType, FvRsBDToOutList) upgradedStateData.FvRsBDToOut = FvRsBDToOutSet - FvRsBDToProfileObject := FvRsBDToProfileFvBDResourceModel{ - Annotation: basetypes.NewStringNull(), - TnL3extOutName: basetypes.NewStringNull(), - TnRtctrlProfileName: basetypes.NewStringValue(GetMOName(priorStateData.FvRsBDToProfile.ValueString())), - TagAnnotation: basetypes.NewSetNull(types.ObjectType{ - AttrTypes: map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - }, - }), - TagTag: basetypes.NewSetNull(types.ObjectType{ - AttrTypes: map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - }, - }), - } - fvRsBDToProfileObject, _ := types.ObjectValueFrom(ctx, FvRsBDToProfileFvBDType, FvRsBDToProfileObject) - upgradedStateData.FvRsBDToProfile = fvRsBDToProfileObject + upgradedStateData.FvRsBDToProfile = types.ObjectNull(FvRsBDToProfileFvBDType) FvRsBDToRelayPObject := FvRsBDToRelayPFvBDResourceModel{ Annotation: basetypes.NewStringNull(), @@ -1961,6 +2053,9 @@ func setFvBDLegacyAttributes(ctx context.Context, diags *diag.Diagnostics, data, Deprecated_relation_fv_rs_bd_flood_toSet, _ := types.SetValueFrom(ctx, types.StringType, []string{}) data.Deprecated_relation_fv_rs_bd_flood_to = Deprecated_relation_fv_rs_bd_flood_toSet } + if !staticData.Deprecated_relation_fv_rs_bd_to_profile.IsUnknown() { + data.Deprecated_relation_fv_rs_bd_to_profile = staticData.Deprecated_relation_fv_rs_bd_to_profile + } attributes := classReadInfo[0].(map[string]interface{})["attributes"].(map[string]interface{}) for attributeName, attributeValue := range attributes { if attributeName == "arpFlood" { @@ -2012,8 +2107,8 @@ func setFvBDLegacyAttributes(ctx context.Context, diags *diag.Diagnostics, data, data.DeprecatedFvRsABDPolMonPol = basetypes.NewStringNull() data.DeprecatedFvRsBDToFhs = basetypes.NewStringNull() data.DeprecatedFvRsBDToNdP = basetypes.NewStringNull() + DeprecatedFvRsBDToNetflowMonitorPolFvBDList := make([]FvRsBDToNetflowMonitorPolFvBDResourceModelV1, 0) DeprecatedFvRsBDToOutFvBDList := make([]string, 0) - data.DeprecatedFvRsBDToProfile = basetypes.NewStringNull() data.DeprecatedFvRsBDToRelayP = basetypes.NewStringNull() data.DeprecatedFvRsBdToEpRet = basetypes.NewStringNull() data.DeprecatedFvRsCtx = basetypes.NewStringNull() @@ -2047,17 +2142,22 @@ func setFvBDLegacyAttributes(ctx context.Context, diags *diag.Diagnostics, data, } } } - if childClassName == "fvRsBDToOut" { + if childClassName == "fvRsBDToNetflowMonitorPol" { + DeprecatedFvRsBDToNetflowMonitorPolFvBD := getEmptyFvRsBDToNetflowMonitorPolFvBDResourceModelV1() for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "tDn" && childAttributeValue != "" && !ContainsString(DeprecatedFvRsBDToOutFvBDList, childAttributeValue.(string)) { - DeprecatedFvRsBDToOutFvBDList = append(DeprecatedFvRsBDToOutFvBDList, childAttributeValue.(string)) + if childAttributeName == "fltType" { + DeprecatedFvRsBDToNetflowMonitorPolFvBD.FltType = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "tDn" { + DeprecatedFvRsBDToNetflowMonitorPolFvBD.TnNetflowMonitorPolName = basetypes.NewStringValue(childAttributeValue.(string)) } } + DeprecatedFvRsBDToNetflowMonitorPolFvBDList = append(DeprecatedFvRsBDToNetflowMonitorPolFvBDList, DeprecatedFvRsBDToNetflowMonitorPolFvBD) } - if childClassName == "fvRsBDToProfile" { + if childClassName == "fvRsBDToOut" { for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "tDn" { - data.DeprecatedFvRsBDToProfile = basetypes.NewStringValue(childAttributeValue.(string)) + if childAttributeName == "tDn" && childAttributeValue != "" && !ContainsString(DeprecatedFvRsBDToOutFvBDList, childAttributeValue.(string)) { + DeprecatedFvRsBDToOutFvBDList = append(DeprecatedFvRsBDToOutFvBDList, childAttributeValue.(string)) } } } @@ -2098,7 +2198,8 @@ func setFvBDLegacyAttributes(ctx context.Context, diags *diag.Diagnostics, data, } } } - data.DeprecatedFvRsBDToNetflowMonitorPol = types.SetNull(deprecatedFvRsBDToNetflowMonitorPolType) + fvRsBDToNetflowMonitorPolSet, _ := types.SetValueFrom(ctx, data.DeprecatedFvRsBDToNetflowMonitorPol.ElementType(ctx), DeprecatedFvRsBDToNetflowMonitorPolFvBDList) + data.DeprecatedFvRsBDToNetflowMonitorPol = fvRsBDToNetflowMonitorPolSet fvRsBDToOutSet, _ := types.SetValueFrom(ctx, data.DeprecatedFvRsBDToOut.ElementType(ctx), DeprecatedFvRsBDToOutFvBDList) data.DeprecatedFvRsBDToOut = fvRsBDToOutSet } @@ -2186,151 +2287,76 @@ func (r *FvBDResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRe } } - if !configData.ArpFlood.IsNull() { - planData.DeprecatedArpFlood = configData.ArpFlood - } else if !configData.DeprecatedArpFlood.IsNull() { + if !configData.DeprecatedArpFlood.IsNull() { planData.ArpFlood = configData.DeprecatedArpFlood - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedArpFlood = stateData.DeprecatedArpFlood } - if !configData.EpClear.IsNull() { - planData.DeprecatedEpClear = configData.EpClear - } else if !configData.DeprecatedEpClear.IsNull() { + if !configData.DeprecatedEpClear.IsNull() { planData.EpClear = configData.DeprecatedEpClear - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedEpClear = stateData.DeprecatedEpClear } - if !configData.EpMoveDetectMode.IsNull() { - planData.DeprecatedEpMoveDetectMode = configData.EpMoveDetectMode - } else if !configData.DeprecatedEpMoveDetectMode.IsNull() { + if !configData.DeprecatedEpMoveDetectMode.IsNull() { planData.EpMoveDetectMode = configData.DeprecatedEpMoveDetectMode - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedEpMoveDetectMode = stateData.DeprecatedEpMoveDetectMode } - if !configData.HostBasedRouting.IsNull() { - planData.DeprecatedHostBasedRouting = configData.HostBasedRouting - } else if !configData.DeprecatedHostBasedRouting.IsNull() { + if !configData.DeprecatedHostBasedRouting.IsNull() { planData.HostBasedRouting = configData.DeprecatedHostBasedRouting - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedHostBasedRouting = stateData.DeprecatedHostBasedRouting } - if !configData.IntersiteBumTrafficAllow.IsNull() { - planData.DeprecatedIntersiteBumTrafficAllow = configData.IntersiteBumTrafficAllow - } else if !configData.DeprecatedIntersiteBumTrafficAllow.IsNull() { + if !configData.DeprecatedIntersiteBumTrafficAllow.IsNull() { planData.IntersiteBumTrafficAllow = configData.DeprecatedIntersiteBumTrafficAllow - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedIntersiteBumTrafficAllow = stateData.DeprecatedIntersiteBumTrafficAllow } - if !configData.Ipv6McastAllow.IsNull() { - planData.DeprecatedIpv6McastAllow = configData.Ipv6McastAllow - } else if !configData.DeprecatedIpv6McastAllow.IsNull() { + if !configData.DeprecatedIpv6McastAllow.IsNull() { planData.Ipv6McastAllow = configData.DeprecatedIpv6McastAllow - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedIpv6McastAllow = stateData.DeprecatedIpv6McastAllow } - if !configData.LlAddr.IsNull() { - planData.DeprecatedLlAddr = configData.LlAddr - } else if !configData.DeprecatedLlAddr.IsNull() { + if !configData.DeprecatedLlAddr.IsNull() { planData.LlAddr = configData.DeprecatedLlAddr - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedLlAddr = stateData.DeprecatedLlAddr } - if !configData.Mac.IsNull() { - planData.DeprecatedMac = configData.Mac - } else if !configData.DeprecatedMac.IsNull() { + if !configData.DeprecatedMac.IsNull() { planData.Mac = configData.DeprecatedMac - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedMac = stateData.DeprecatedMac } - if !configData.McastAllow.IsNull() { - planData.DeprecatedMcastAllow = configData.McastAllow - } else if !configData.DeprecatedMcastAllow.IsNull() { + if !configData.DeprecatedMcastAllow.IsNull() { planData.McastAllow = configData.DeprecatedMcastAllow - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedMcastAllow = stateData.DeprecatedMcastAllow } - if !configData.MultiDstPktAct.IsNull() { - planData.DeprecatedMultiDstPktAct = configData.MultiDstPktAct - } else if !configData.DeprecatedMultiDstPktAct.IsNull() { + if !configData.DeprecatedMultiDstPktAct.IsNull() { planData.MultiDstPktAct = configData.DeprecatedMultiDstPktAct - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedMultiDstPktAct = stateData.DeprecatedMultiDstPktAct } - if !configData.ParentDn.IsNull() { - planData.DeprecatedParentDn = configData.ParentDn - } else if !configData.DeprecatedParentDn.IsNull() { + if !configData.DeprecatedParentDn.IsNull() { planData.ParentDn = configData.DeprecatedParentDn - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedParentDn = stateData.DeprecatedParentDn } - if !configData.UnicastRoute.IsNull() { - planData.DeprecatedUnicastRoute = configData.UnicastRoute - } else if !configData.DeprecatedUnicastRoute.IsNull() { + if !configData.DeprecatedUnicastRoute.IsNull() { planData.UnicastRoute = configData.DeprecatedUnicastRoute - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedUnicastRoute = stateData.DeprecatedUnicastRoute } - if !configData.UnkMacUcastAct.IsNull() { - planData.DeprecatedUnkMacUcastAct = configData.UnkMacUcastAct - } else if !configData.DeprecatedUnkMacUcastAct.IsNull() { + if !configData.DeprecatedUnkMacUcastAct.IsNull() { planData.UnkMacUcastAct = configData.DeprecatedUnkMacUcastAct - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedUnkMacUcastAct = stateData.DeprecatedUnkMacUcastAct } - if !configData.UnkMcastAct.IsNull() { - planData.DeprecatedUnkMcastAct = configData.UnkMcastAct - } else if !configData.DeprecatedUnkMcastAct.IsNull() { + if !configData.DeprecatedUnkMcastAct.IsNull() { planData.UnkMcastAct = configData.DeprecatedUnkMcastAct - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedUnkMcastAct = stateData.DeprecatedUnkMcastAct } - if !configData.V6unkMcastAct.IsNull() { - planData.DeprecatedV6unkMcastAct = configData.V6unkMcastAct - } else if !configData.DeprecatedV6unkMcastAct.IsNull() { + if !configData.DeprecatedV6unkMcastAct.IsNull() { planData.V6unkMcastAct = configData.DeprecatedV6unkMcastAct - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedV6unkMcastAct = stateData.DeprecatedV6unkMcastAct } - if !configData.Vmac.IsNull() { - planData.DeprecatedVmac = configData.Vmac - } else if !configData.DeprecatedVmac.IsNull() { + if !configData.DeprecatedVmac.IsNull() { planData.Vmac = configData.DeprecatedVmac - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedVmac = stateData.DeprecatedVmac } - if !configData.FvRsBDToRelayP.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsBDToRelayP.Attributes()) { - planData.FvRsBDToRelayP = configData.FvRsBDToRelayP - planData.DeprecatedFvRsBDToRelayP = basetypes.NewStringNull() - } else { - var attributeValues FvRsBDToRelayPFvBDResourceModel - configData.FvRsBDToRelayP.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsBDToRelayP.ValueString()) == attributeValues.TnDhcpRelayPName.ValueString() && !attributeValues.TnDhcpRelayPName.IsNull() { - planData.DeprecatedFvRsBDToRelayP = stateData.DeprecatedFvRsBDToRelayP - } - } - } else if !configData.DeprecatedFvRsBDToRelayP.IsNull() { + if !configData.DeprecatedFvRsBDToRelayP.IsNull() { var newAttributeValues FvRsBDToRelayPFvBDResourceModel tagAnnotationFvRsBDToRelayPFvBDValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsBDToRelayPFvBDType, make([]TagAnnotationFvRsBDToRelayPFvBDResourceModel, 0)) tagTagFvRsBDToRelayPFvBDValue, _ := types.SetValueFrom(ctx, TagTagFvRsBDToRelayPFvBDType, make([]TagTagFvRsBDToRelayPFvBDResourceModel, 0)) annotationValue := planData.Annotation - if stateData != nil { + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.FvRsBDToRelayP.Attributes()) { stateData.FvRsBDToRelayP.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) annotationValue = newAttributeValues.Annotation tagAnnotationFvRsBDToRelayPFvBDValue = newAttributeValues.TagAnnotation @@ -2348,29 +2374,18 @@ func (r *FvBDResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRe } FvRsBDToRelayPObject, _ := types.ObjectValueFrom(ctx, FvRsBDToRelayPFvBDType, FvRsBDToRelayP) planData.FvRsBDToRelayP = FvRsBDToRelayPObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsBDToRelayP = stateData.DeprecatedFvRsBDToRelayP } - if !configData.FvRsBdToEpRet.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsBdToEpRet.Attributes()) { - planData.FvRsBdToEpRet = configData.FvRsBdToEpRet - planData.DeprecatedFvRsBdToEpRet = basetypes.NewStringNull() - } else { - var attributeValues FvRsBdToEpRetFvBDResourceModel - configData.FvRsBdToEpRet.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsBdToEpRet.ValueString()) == attributeValues.TnFvEpRetPolName.ValueString() && !attributeValues.TnFvEpRetPolName.IsNull() { - planData.DeprecatedFvRsBdToEpRet = stateData.DeprecatedFvRsBdToEpRet - } - } - } else if !configData.DeprecatedFvRsBdToEpRet.IsNull() { + if !configData.DeprecatedFvRsBdToEpRet.IsNull() { var newAttributeValues FvRsBdToEpRetFvBDResourceModel tagAnnotationFvRsBdToEpRetFvBDValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsBdToEpRetFvBDType, make([]TagAnnotationFvRsBdToEpRetFvBDResourceModel, 0)) tagTagFvRsBdToEpRetFvBDValue, _ := types.SetValueFrom(ctx, TagTagFvRsBdToEpRetFvBDType, make([]TagTagFvRsBdToEpRetFvBDResourceModel, 0)) annotationValue := planData.Annotation - if stateData != nil { + resolveActValue := basetypes.NewStringUnknown() + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.FvRsBdToEpRet.Attributes()) { stateData.FvRsBdToEpRet.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) annotationValue = newAttributeValues.Annotation + resolveActValue = newAttributeValues.ResolveAct tagAnnotationFvRsBdToEpRetFvBDValue = newAttributeValues.TagAnnotation tagTagFvRsBdToEpRetFvBDValue = newAttributeValues.TagTag } @@ -2380,34 +2395,21 @@ func (r *FvBDResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRe } FvRsBdToEpRet := FvRsBdToEpRetFvBDResourceModel{ Annotation: annotationValue, - ResolveAct: basetypes.NewStringNull(), + ResolveAct: resolveActValue, TnFvEpRetPolName: tnFvEpRetPolNameValue, TagAnnotation: tagAnnotationFvRsBdToEpRetFvBDValue, TagTag: tagTagFvRsBdToEpRetFvBDValue, } FvRsBdToEpRetObject, _ := types.ObjectValueFrom(ctx, FvRsBdToEpRetFvBDType, FvRsBdToEpRet) planData.FvRsBdToEpRet = FvRsBdToEpRetObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsBdToEpRet = stateData.DeprecatedFvRsBdToEpRet } - if !configData.FvRsBDToFhs.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsBDToFhs.Attributes()) { - planData.FvRsBDToFhs = configData.FvRsBDToFhs - planData.DeprecatedFvRsBDToFhs = basetypes.NewStringNull() - } else { - var attributeValues FvRsBDToFhsFvBDResourceModel - configData.FvRsBDToFhs.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsBDToFhs.ValueString()) == attributeValues.TnFhsBDPolName.ValueString() && !attributeValues.TnFhsBDPolName.IsNull() { - planData.DeprecatedFvRsBDToFhs = stateData.DeprecatedFvRsBDToFhs - } - } - } else if !configData.DeprecatedFvRsBDToFhs.IsNull() { + if !configData.DeprecatedFvRsBDToFhs.IsNull() { var newAttributeValues FvRsBDToFhsFvBDResourceModel tagAnnotationFvRsBDToFhsFvBDValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsBDToFhsFvBDType, make([]TagAnnotationFvRsBDToFhsFvBDResourceModel, 0)) tagTagFvRsBDToFhsFvBDValue, _ := types.SetValueFrom(ctx, TagTagFvRsBDToFhsFvBDType, make([]TagTagFvRsBDToFhsFvBDResourceModel, 0)) annotationValue := planData.Annotation - if stateData != nil { + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.FvRsBDToFhs.Attributes()) { stateData.FvRsBDToFhs.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) annotationValue = newAttributeValues.Annotation tagAnnotationFvRsBDToFhsFvBDValue = newAttributeValues.TagAnnotation @@ -2425,27 +2427,14 @@ func (r *FvBDResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRe } FvRsBDToFhsObject, _ := types.ObjectValueFrom(ctx, FvRsBDToFhsFvBDType, FvRsBDToFhs) planData.FvRsBDToFhs = FvRsBDToFhsObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsBDToFhs = stateData.DeprecatedFvRsBDToFhs } - if !configData.FvRsIgmpsn.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsIgmpsn.Attributes()) { - planData.FvRsIgmpsn = configData.FvRsIgmpsn - planData.DeprecatedFvRsIgmpsn = basetypes.NewStringNull() - } else { - var attributeValues FvRsIgmpsnFvBDResourceModel - configData.FvRsIgmpsn.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsIgmpsn.ValueString()) == attributeValues.TnIgmpSnoopPolName.ValueString() && !attributeValues.TnIgmpSnoopPolName.IsNull() { - planData.DeprecatedFvRsIgmpsn = stateData.DeprecatedFvRsIgmpsn - } - } - } else if !configData.DeprecatedFvRsIgmpsn.IsNull() { + if !configData.DeprecatedFvRsIgmpsn.IsNull() { var newAttributeValues FvRsIgmpsnFvBDResourceModel tagAnnotationFvRsIgmpsnFvBDValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsIgmpsnFvBDType, make([]TagAnnotationFvRsIgmpsnFvBDResourceModel, 0)) tagTagFvRsIgmpsnFvBDValue, _ := types.SetValueFrom(ctx, TagTagFvRsIgmpsnFvBDType, make([]TagTagFvRsIgmpsnFvBDResourceModel, 0)) annotationValue := planData.Annotation - if stateData != nil { + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.FvRsIgmpsn.Attributes()) { stateData.FvRsIgmpsn.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) annotationValue = newAttributeValues.Annotation tagAnnotationFvRsIgmpsnFvBDValue = newAttributeValues.TagAnnotation @@ -2463,37 +2452,13 @@ func (r *FvBDResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRe } FvRsIgmpsnObject, _ := types.ObjectValueFrom(ctx, FvRsIgmpsnFvBDType, FvRsIgmpsn) planData.FvRsIgmpsn = FvRsIgmpsnObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsIgmpsn = stateData.DeprecatedFvRsIgmpsn } - if !configData.FvRsBDToOut.IsNull() && stateData != nil { - var attributeValues []FvRsBDToOutFvBDResourceModel - var newAttributeValues, stateAttributeValues []string - configData.FvRsBDToOut.ElementsAs(ctx, &attributeValues, false) - stateData.DeprecatedFvRsBDToOut.ElementsAs(ctx, &stateAttributeValues, false) - for _, attributeValue := range attributeValues { - newAttributeValues = append(newAttributeValues, attributeValue.TnL3extOutName.ValueString()) - } - - if len(newAttributeValues) == len(stateAttributeValues) { - allMatchState := true - for _, stateAttributeValue := range stateAttributeValues { - if !ContainsString(newAttributeValues, GetMOName(stateAttributeValue)) { - allMatchState = false - break - } - } - if allMatchState { - FvRsBDToOutSet, _ := types.SetValueFrom(ctx, basetypes.StringType{}, stateAttributeValues) - planData.DeprecatedFvRsBDToOut = FvRsBDToOutSet - } - } - } else if !configData.DeprecatedFvRsBDToOut.IsNull() { + if !configData.DeprecatedFvRsBDToOut.IsNull() { FvRsBDToOutList := make([]FvRsBDToOutFvBDResourceModel, 0) var attributeValues []basetypes.StringValue var newAttributeValues []FvRsBDToOutFvBDResourceModel - configData.DeprecatedFvRsBDToOut.ElementsAs(ctx, &attributeValues, false) + planData.DeprecatedFvRsBDToOut.ElementsAs(ctx, &attributeValues, false) if stateData != nil { stateData.FvRsBDToOut.ElementsAs(ctx, &newAttributeValues, false) } @@ -2528,27 +2493,14 @@ func (r *FvBDResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRe } FvRsBDToOutSet, _ := types.SetValueFrom(ctx, FvRsBDToOutFvBDType, FvRsBDToOutList) planData.FvRsBDToOut = FvRsBDToOutSet - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsBDToOut = stateData.DeprecatedFvRsBDToOut } - if !configData.FvRsMldsn.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsMldsn.Attributes()) { - planData.FvRsMldsn = configData.FvRsMldsn - planData.DeprecatedFvRsMldsn = basetypes.NewStringNull() - } else { - var attributeValues FvRsMldsnFvBDResourceModel - configData.FvRsMldsn.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsMldsn.ValueString()) == attributeValues.TnMldSnoopPolName.ValueString() && !attributeValues.TnMldSnoopPolName.IsNull() { - planData.DeprecatedFvRsMldsn = stateData.DeprecatedFvRsMldsn - } - } - } else if !configData.DeprecatedFvRsMldsn.IsNull() { + if !configData.DeprecatedFvRsMldsn.IsNull() { var newAttributeValues FvRsMldsnFvBDResourceModel tagAnnotationFvRsMldsnFvBDValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsMldsnFvBDType, make([]TagAnnotationFvRsMldsnFvBDResourceModel, 0)) tagTagFvRsMldsnFvBDValue, _ := types.SetValueFrom(ctx, TagTagFvRsMldsnFvBDType, make([]TagTagFvRsMldsnFvBDResourceModel, 0)) annotationValue := planData.Annotation - if stateData != nil { + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.FvRsMldsn.Attributes()) { stateData.FvRsMldsn.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) annotationValue = newAttributeValues.Annotation tagAnnotationFvRsMldsnFvBDValue = newAttributeValues.TagAnnotation @@ -2566,27 +2518,14 @@ func (r *FvBDResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRe } FvRsMldsnObject, _ := types.ObjectValueFrom(ctx, FvRsMldsnFvBDType, FvRsMldsn) planData.FvRsMldsn = FvRsMldsnObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsMldsn = stateData.DeprecatedFvRsMldsn } - if !configData.FvRsABDPolMonPol.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsABDPolMonPol.Attributes()) { - planData.FvRsABDPolMonPol = configData.FvRsABDPolMonPol - planData.DeprecatedFvRsABDPolMonPol = basetypes.NewStringNull() - } else { - var attributeValues FvRsABDPolMonPolFvBDResourceModel - configData.FvRsABDPolMonPol.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsABDPolMonPol.ValueString()) == attributeValues.TnMonEPGPolName.ValueString() && !attributeValues.TnMonEPGPolName.IsNull() { - planData.DeprecatedFvRsABDPolMonPol = stateData.DeprecatedFvRsABDPolMonPol - } - } - } else if !configData.DeprecatedFvRsABDPolMonPol.IsNull() { + if !configData.DeprecatedFvRsABDPolMonPol.IsNull() { var newAttributeValues FvRsABDPolMonPolFvBDResourceModel tagAnnotationFvRsABDPolMonPolFvBDValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsABDPolMonPolFvBDType, make([]TagAnnotationFvRsABDPolMonPolFvBDResourceModel, 0)) tagTagFvRsABDPolMonPolFvBDValue, _ := types.SetValueFrom(ctx, TagTagFvRsABDPolMonPolFvBDType, make([]TagTagFvRsABDPolMonPolFvBDResourceModel, 0)) annotationValue := planData.Annotation - if stateData != nil { + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.FvRsABDPolMonPol.Attributes()) { stateData.FvRsABDPolMonPol.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) annotationValue = newAttributeValues.Annotation tagAnnotationFvRsABDPolMonPolFvBDValue = newAttributeValues.TagAnnotation @@ -2604,27 +2543,14 @@ func (r *FvBDResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRe } FvRsABDPolMonPolObject, _ := types.ObjectValueFrom(ctx, FvRsABDPolMonPolFvBDType, FvRsABDPolMonPol) planData.FvRsABDPolMonPol = FvRsABDPolMonPolObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsABDPolMonPol = stateData.DeprecatedFvRsABDPolMonPol } - if !configData.FvRsBDToNdP.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsBDToNdP.Attributes()) { - planData.FvRsBDToNdP = configData.FvRsBDToNdP - planData.DeprecatedFvRsBDToNdP = basetypes.NewStringNull() - } else { - var attributeValues FvRsBDToNdPFvBDResourceModel - configData.FvRsBDToNdP.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsBDToNdP.ValueString()) == attributeValues.TnNdIfPolName.ValueString() && !attributeValues.TnNdIfPolName.IsNull() { - planData.DeprecatedFvRsBDToNdP = stateData.DeprecatedFvRsBDToNdP - } - } - } else if !configData.DeprecatedFvRsBDToNdP.IsNull() { + if !configData.DeprecatedFvRsBDToNdP.IsNull() { var newAttributeValues FvRsBDToNdPFvBDResourceModel tagAnnotationFvRsBDToNdPFvBDValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsBDToNdPFvBDType, make([]TagAnnotationFvRsBDToNdPFvBDResourceModel, 0)) tagTagFvRsBDToNdPFvBDValue, _ := types.SetValueFrom(ctx, TagTagFvRsBDToNdPFvBDType, make([]TagTagFvRsBDToNdPFvBDResourceModel, 0)) annotationValue := planData.Annotation - if stateData != nil { + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.FvRsBDToNdP.Attributes()) { stateData.FvRsBDToNdP.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) annotationValue = newAttributeValues.Annotation tagAnnotationFvRsBDToNdPFvBDValue = newAttributeValues.TagAnnotation @@ -2642,66 +2568,14 @@ func (r *FvBDResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRe } FvRsBDToNdPObject, _ := types.ObjectValueFrom(ctx, FvRsBDToNdPFvBDType, FvRsBDToNdP) planData.FvRsBDToNdP = FvRsBDToNdPObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsBDToNdP = stateData.DeprecatedFvRsBDToNdP - } - - if !configData.FvRsBDToProfile.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsBDToProfile.Attributes()) { - planData.FvRsBDToProfile = configData.FvRsBDToProfile - planData.DeprecatedFvRsBDToProfile = basetypes.NewStringNull() - } else { - var attributeValues FvRsBDToProfileFvBDResourceModel - configData.FvRsBDToProfile.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsBDToProfile.ValueString()) == attributeValues.TnRtctrlProfileName.ValueString() && !attributeValues.TnRtctrlProfileName.IsNull() { - planData.DeprecatedFvRsBDToProfile = stateData.DeprecatedFvRsBDToProfile - } - } - } else if !configData.DeprecatedFvRsBDToProfile.IsNull() { - var newAttributeValues FvRsBDToProfileFvBDResourceModel - tagAnnotationFvRsBDToProfileFvBDValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsBDToProfileFvBDType, make([]TagAnnotationFvRsBDToProfileFvBDResourceModel, 0)) - tagTagFvRsBDToProfileFvBDValue, _ := types.SetValueFrom(ctx, TagTagFvRsBDToProfileFvBDType, make([]TagTagFvRsBDToProfileFvBDResourceModel, 0)) - annotationValue := planData.Annotation - if stateData != nil { - stateData.FvRsBDToProfile.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) - annotationValue = newAttributeValues.Annotation - tagAnnotationFvRsBDToProfileFvBDValue = newAttributeValues.TagAnnotation - tagTagFvRsBDToProfileFvBDValue = newAttributeValues.TagTag - } - tnRtctrlProfileNameValue := basetypes.NewStringUnknown() - if !configData.DeprecatedFvRsBDToProfile.IsUnknown() { - tnRtctrlProfileNameValue = basetypes.NewStringValue(GetMOName(configData.DeprecatedFvRsBDToProfile.ValueString())) - } - FvRsBDToProfile := FvRsBDToProfileFvBDResourceModel{ - Annotation: annotationValue, - TnL3extOutName: basetypes.NewStringValue(""), - TnRtctrlProfileName: tnRtctrlProfileNameValue, - TagAnnotation: tagAnnotationFvRsBDToProfileFvBDValue, - TagTag: tagTagFvRsBDToProfileFvBDValue, - } - FvRsBDToProfileObject, _ := types.ObjectValueFrom(ctx, FvRsBDToProfileFvBDType, FvRsBDToProfile) - planData.FvRsBDToProfile = FvRsBDToProfileObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsBDToProfile = stateData.DeprecatedFvRsBDToProfile } - if !configData.FvRsCtx.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsCtx.Attributes()) { - planData.FvRsCtx = configData.FvRsCtx - planData.DeprecatedFvRsCtx = basetypes.NewStringNull() - } else { - var attributeValues FvRsCtxFvBDResourceModel - configData.FvRsCtx.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsCtx.ValueString()) == attributeValues.TnFvCtxName.ValueString() && !attributeValues.TnFvCtxName.IsNull() { - planData.DeprecatedFvRsCtx = stateData.DeprecatedFvRsCtx - } - } - } else if !configData.DeprecatedFvRsCtx.IsNull() { + if !configData.DeprecatedFvRsCtx.IsNull() { var newAttributeValues FvRsCtxFvBDResourceModel tagAnnotationFvRsCtxFvBDValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsCtxFvBDType, make([]TagAnnotationFvRsCtxFvBDResourceModel, 0)) tagTagFvRsCtxFvBDValue, _ := types.SetValueFrom(ctx, TagTagFvRsCtxFvBDType, make([]TagTagFvRsCtxFvBDResourceModel, 0)) annotationValue := planData.Annotation - if stateData != nil { + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.FvRsCtx.Attributes()) { stateData.FvRsCtx.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) annotationValue = newAttributeValues.Annotation tagAnnotationFvRsCtxFvBDValue = newAttributeValues.TagAnnotation @@ -2719,48 +2593,241 @@ func (r *FvBDResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRe } FvRsCtxObject, _ := types.ObjectValueFrom(ctx, FvRsCtxFvBDType, FvRsCtx) planData.FvRsCtx = FvRsCtxObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsCtx = stateData.DeprecatedFvRsCtx } - planData.DeprecatedFvRsBDToNetflowMonitorPol = types.SetNull(deprecatedFvRsBDToNetflowMonitorPolType) if !configData.DeprecatedFvRsBDToNetflowMonitorPol.IsNull() { FvRsBDToNetflowMonitorPolList := make([]FvRsBDToNetflowMonitorPolFvBDResourceModel, 0) var attributeValues []FvRsBDToNetflowMonitorPolFvBDResourceModelV1 var newAttributeValues []FvRsBDToNetflowMonitorPolFvBDResourceModel - configData.DeprecatedFvRsBDToNetflowMonitorPol.ElementsAs(ctx, &attributeValues, false) - annotationValue := planData.Annotation if stateData != nil { stateData.FvRsBDToNetflowMonitorPol.ElementsAs(ctx, &newAttributeValues, false) - for _, newAttributeValue := range newAttributeValues { - annotationValue = newAttributeValue.Annotation - } } + planData.DeprecatedFvRsBDToNetflowMonitorPol.ElementsAs(ctx, &attributeValues, false) for _, attributeValue := range attributeValues { + plannedFvRsBDToNetflowMonitorPol := FvRsBDToNetflowMonitorPolFvBDResourceModel{} + foundAttributeValue := false + for _, newAttributeValue := range newAttributeValues { + if newAttributeValue.TnNetflowMonitorPolName.ValueString() == GetMOName(attributeValue.TnNetflowMonitorPolName.ValueString()) { + plannedFvRsBDToNetflowMonitorPol = newAttributeValue + foundAttributeValue = true + break + } + } tnNetflowMonitorPolNameValue := basetypes.NewStringUnknown() if !attributeValue.TnNetflowMonitorPolName.IsUnknown() { tnNetflowMonitorPolNameValue = basetypes.NewStringValue(GetMOName(attributeValue.TnNetflowMonitorPolName.ValueString())) } - FvRsBDToNetflowMonitorPol := FvRsBDToNetflowMonitorPolFvBDResourceModel{ - Annotation: annotationValue, + Annotation: planData.Annotation, FltType: attributeValue.FltType, TnNetflowMonitorPolName: tnNetflowMonitorPolNameValue, } + if foundAttributeValue { + FvRsBDToNetflowMonitorPol.Annotation = plannedFvRsBDToNetflowMonitorPol.Annotation + } tagAnnotationFvRsBDToNetflowMonitorPolFvBDValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsBDToNetflowMonitorPolFvBDType, make([]TagAnnotationFvRsBDToNetflowMonitorPolFvBDResourceModel, 0)) FvRsBDToNetflowMonitorPol.TagAnnotation = tagAnnotationFvRsBDToNetflowMonitorPolFvBDValue tagTagFvRsBDToNetflowMonitorPolFvBDValue, _ := types.SetValueFrom(ctx, TagTagFvRsBDToNetflowMonitorPolFvBDType, make([]TagTagFvRsBDToNetflowMonitorPolFvBDResourceModel, 0)) FvRsBDToNetflowMonitorPol.TagTag = tagTagFvRsBDToNetflowMonitorPolFvBDValue FvRsBDToNetflowMonitorPolList = append(FvRsBDToNetflowMonitorPolList, FvRsBDToNetflowMonitorPol) } - FvRsBDToNetflowMonitorPolSet, _ := types.SetValueFrom(ctx, FvRsBDToNetflowMonitorPolFvBDType, FvRsBDToNetflowMonitorPolList) planData.FvRsBDToNetflowMonitorPol = FvRsBDToNetflowMonitorPolSet + } else if !configData.FvRsBDToNetflowMonitorPol.IsNull() && stateData == nil { + setUnknownDeprecatedFvRsBDToNetflowMonitorPolFvBDResourceModelToPlan(ctx, planData) + } + + // Workaround to compare the state with plan to avoid plan changes with only known after apply + if stateData != nil { + avoidFvBDPlanChangeForKnownAfterApplyOnly(ctx, planData, stateData, configData) } resp.Diagnostics.Append(resp.Plan.Set(ctx, &planData)...) } } +func setUnknownDeprecatedFvRsBDToNetflowMonitorPolFvBDResourceModelToPlan(ctx context.Context, planData *FvBDResourceModel) { + var attributeValues []FvRsBDToNetflowMonitorPolFvBDResourceModel + var legacyAttributeValues []FvRsBDToNetflowMonitorPolFvBDResourceModelV1 + planData.FvRsBDToNetflowMonitorPol.ElementsAs(ctx, &attributeValues, false) + for i := 0; i < len(attributeValues); i++ { + legacyAttributeValues = append(legacyAttributeValues, FvRsBDToNetflowMonitorPolFvBDResourceModelV1{ + FltType: basetypes.NewStringUnknown(), + TnNetflowMonitorPolName: basetypes.NewStringUnknown(), + }) + } + DeprecatedFvRsBDToNetflowMonitorPolSet, _ := types.SetValueFrom(ctx, deprecatedFvRsBDToNetflowMonitorPolType, legacyAttributeValues) + planData.DeprecatedFvRsBDToNetflowMonitorPol = DeprecatedFvRsBDToNetflowMonitorPolSet +} + +func avoidFvBDPlanChangeForKnownAfterApplyOnly(ctx context.Context, planData, stateData, configData *FvBDResourceModel) { + // Set read-only and deprecated attributes in planData from stateData + planData.PcTag = stateData.PcTag + planData.Scope = stateData.Scope + planData.Seg = stateData.Seg + if configData.DeprecatedArpFlood.IsNull() { + planData.DeprecatedArpFlood = stateData.DeprecatedArpFlood + } + if configData.DeprecatedEpClear.IsNull() { + planData.DeprecatedEpClear = stateData.DeprecatedEpClear + } + if configData.DeprecatedEpMoveDetectMode.IsNull() { + planData.DeprecatedEpMoveDetectMode = stateData.DeprecatedEpMoveDetectMode + } + if configData.DeprecatedHostBasedRouting.IsNull() { + planData.DeprecatedHostBasedRouting = stateData.DeprecatedHostBasedRouting + } + if configData.DeprecatedIntersiteBumTrafficAllow.IsNull() { + planData.DeprecatedIntersiteBumTrafficAllow = stateData.DeprecatedIntersiteBumTrafficAllow + } + if configData.DeprecatedIpv6McastAllow.IsNull() { + planData.DeprecatedIpv6McastAllow = stateData.DeprecatedIpv6McastAllow + } + if configData.DeprecatedLlAddr.IsNull() { + planData.DeprecatedLlAddr = stateData.DeprecatedLlAddr + } + if configData.DeprecatedMac.IsNull() { + planData.DeprecatedMac = stateData.DeprecatedMac + } + if configData.DeprecatedMcastAllow.IsNull() { + planData.DeprecatedMcastAllow = stateData.DeprecatedMcastAllow + } + if configData.DeprecatedMultiDstPktAct.IsNull() { + planData.DeprecatedMultiDstPktAct = stateData.DeprecatedMultiDstPktAct + } + if configData.DeprecatedParentDn.IsNull() { + planData.DeprecatedParentDn = stateData.DeprecatedParentDn + } + if configData.DeprecatedUnicastRoute.IsNull() { + planData.DeprecatedUnicastRoute = stateData.DeprecatedUnicastRoute + } + if configData.DeprecatedUnkMacUcastAct.IsNull() { + planData.DeprecatedUnkMacUcastAct = stateData.DeprecatedUnkMacUcastAct + } + if configData.DeprecatedUnkMcastAct.IsNull() { + planData.DeprecatedUnkMcastAct = stateData.DeprecatedUnkMcastAct + } + if configData.DeprecatedV6unkMcastAct.IsNull() { + planData.DeprecatedV6unkMcastAct = stateData.DeprecatedV6unkMcastAct + } + if configData.DeprecatedVmac.IsNull() { + planData.DeprecatedVmac = stateData.DeprecatedVmac + } + if configData.DeprecatedFvRsBDToRelayP.IsNull() { + planData.DeprecatedFvRsBDToRelayP = stateData.DeprecatedFvRsBDToRelayP + } + if configData.DeprecatedFvRsBdToEpRet.IsNull() { + planData.DeprecatedFvRsBdToEpRet = stateData.DeprecatedFvRsBdToEpRet + } + if configData.DeprecatedFvRsBDToFhs.IsNull() { + planData.DeprecatedFvRsBDToFhs = stateData.DeprecatedFvRsBDToFhs + } + if configData.DeprecatedFvRsIgmpsn.IsNull() { + planData.DeprecatedFvRsIgmpsn = stateData.DeprecatedFvRsIgmpsn + } + if configData.DeprecatedFvRsBDToOut.IsNull() { + planData.DeprecatedFvRsBDToOut = stateData.DeprecatedFvRsBDToOut + } + if configData.DeprecatedFvRsMldsn.IsNull() { + planData.DeprecatedFvRsMldsn = stateData.DeprecatedFvRsMldsn + } + if configData.DeprecatedFvRsABDPolMonPol.IsNull() { + planData.DeprecatedFvRsABDPolMonPol = stateData.DeprecatedFvRsABDPolMonPol + } + if configData.DeprecatedFvRsBDToNdP.IsNull() { + planData.DeprecatedFvRsBDToNdP = stateData.DeprecatedFvRsBDToNdP + } + if configData.DeprecatedFvRsCtx.IsNull() { + planData.DeprecatedFvRsCtx = stateData.DeprecatedFvRsCtx + } + if configData.DeprecatedFvRsBDToNetflowMonitorPol.IsNull() { + planData.DeprecatedFvRsBDToNetflowMonitorPol = stateData.DeprecatedFvRsBDToNetflowMonitorPol + } + + // Compare the string representation of the planData and stateData because structs cannot be compared directly + if fmt.Sprintf("%s", planData) != fmt.Sprintf("%s", stateData) { + planData.PcTag = basetypes.NewStringUnknown() + planData.Scope = basetypes.NewStringUnknown() + planData.Seg = basetypes.NewStringUnknown() + if configData.DeprecatedArpFlood.IsNull() { + planData.DeprecatedArpFlood = basetypes.NewStringUnknown() + } + if configData.DeprecatedEpClear.IsNull() { + planData.DeprecatedEpClear = basetypes.NewStringUnknown() + } + if configData.DeprecatedEpMoveDetectMode.IsNull() { + planData.DeprecatedEpMoveDetectMode = basetypes.NewStringUnknown() + } + if configData.DeprecatedHostBasedRouting.IsNull() { + planData.DeprecatedHostBasedRouting = basetypes.NewStringUnknown() + } + if configData.DeprecatedIntersiteBumTrafficAllow.IsNull() { + planData.DeprecatedIntersiteBumTrafficAllow = basetypes.NewStringUnknown() + } + if configData.DeprecatedIpv6McastAllow.IsNull() { + planData.DeprecatedIpv6McastAllow = basetypes.NewStringUnknown() + } + if configData.DeprecatedLlAddr.IsNull() { + planData.DeprecatedLlAddr = basetypes.NewStringUnknown() + } + if configData.DeprecatedMac.IsNull() { + planData.DeprecatedMac = basetypes.NewStringUnknown() + } + if configData.DeprecatedMcastAllow.IsNull() { + planData.DeprecatedMcastAllow = basetypes.NewStringUnknown() + } + if configData.DeprecatedMultiDstPktAct.IsNull() { + planData.DeprecatedMultiDstPktAct = basetypes.NewStringUnknown() + } + if configData.DeprecatedParentDn.IsNull() { + planData.DeprecatedParentDn = basetypes.NewStringUnknown() + } + if configData.DeprecatedUnicastRoute.IsNull() { + planData.DeprecatedUnicastRoute = basetypes.NewStringUnknown() + } + if configData.DeprecatedUnkMacUcastAct.IsNull() { + planData.DeprecatedUnkMacUcastAct = basetypes.NewStringUnknown() + } + if configData.DeprecatedUnkMcastAct.IsNull() { + planData.DeprecatedUnkMcastAct = basetypes.NewStringUnknown() + } + if configData.DeprecatedV6unkMcastAct.IsNull() { + planData.DeprecatedV6unkMcastAct = basetypes.NewStringUnknown() + } + if configData.DeprecatedVmac.IsNull() { + planData.DeprecatedVmac = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsBDToRelayP.IsNull() { + planData.DeprecatedFvRsBDToRelayP = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsBdToEpRet.IsNull() { + planData.DeprecatedFvRsBdToEpRet = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsBDToFhs.IsNull() { + planData.DeprecatedFvRsBDToFhs = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsIgmpsn.IsNull() { + planData.DeprecatedFvRsIgmpsn = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsBDToOut.IsNull() { + planData.DeprecatedFvRsBDToOut = basetypes.NewSetUnknown(basetypes.StringType{}) + } + if configData.DeprecatedFvRsMldsn.IsNull() { + planData.DeprecatedFvRsMldsn = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsABDPolMonPol.IsNull() { + planData.DeprecatedFvRsABDPolMonPol = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsBDToNdP.IsNull() { + planData.DeprecatedFvRsBDToNdP = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsCtx.IsNull() { + planData.DeprecatedFvRsCtx = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsBDToNetflowMonitorPol.IsNull() { + setUnknownDeprecatedFvRsBDToNetflowMonitorPolFvBDResourceModelToPlan(ctx, planData) + } + } +} func (r *FvBDResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { tflog.Debug(ctx, "Start metadata of resource: aci_bridge_domain") @@ -2946,6 +3013,15 @@ func (r *FvBDResource) Schema(ctx context.Context, req resource.SchemaRequest, r setplanmodifier.UseStateForUnknown(), }, }, + "relation_fv_rs_bd_to_profile": schema.StringAttribute{ + Optional: true, + Computed: true, + DeprecationMessage: "Attribute `relation_fv_rs_bd_to_profile` is deprecated. The attribute will be removed in the next major version of the provider.", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + }, "relation_fv_rs_bd_to_relay_p": schema.StringAttribute{ Optional: true, Computed: true, @@ -3027,16 +3103,6 @@ func (r *FvBDResource) Schema(ctx context.Context, req resource.SchemaRequest, r }...), }, }, - "relation_fv_rs_bd_to_profile": schema.StringAttribute{ - Optional: true, - Computed: true, - DeprecationMessage: "Attribute 'relation_fv_rs_bd_to_profile' is deprecated, please refer to 'relation_to_route_control_profile.route_control_profile_name' instead. The attribute will be removed in the next major version of the provider.", - Validators: []validator.String{ - stringvalidator.ConflictsWith(path.Expressions{ - path.MatchRoot("relation_to_route_control_profile"), - }...), - }, - }, "relation_fv_rs_ctx": schema.StringAttribute{ Optional: true, Computed: true, @@ -3277,12 +3343,16 @@ func (r *FvBDResource) Schema(ctx context.Context, req resource.SchemaRequest, r MarkdownDescription: `The multiple destination forwarding method for L2 Multicast, Broadcast, and Link Layer traffic types.`, }, "name": schema.StringAttribute{ - Required: true, + Optional: true, + Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, + Validators: []validator.String{ + MakeStringRequired(), + }, MarkdownDescription: `The name of the Bridge Domain object.`, }, "name_alias": schema.StringAttribute{ @@ -3549,6 +3619,7 @@ func (r *FvBDResource) Schema(ctx context.Context, req resource.SchemaRequest, r Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRogueExceptionMacFvBDSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -3958,6 +4029,7 @@ func (r *FvBDResource) Schema(ctx context.Context, req resource.SchemaRequest, r Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsBDToNetflowMonitorPolFvBDSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -4070,6 +4142,7 @@ func (r *FvBDResource) Schema(ctx context.Context, req resource.SchemaRequest, r Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsBDToOutFvBDSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -4828,6 +4901,7 @@ func (r *FvBDResource) Schema(ctx context.Context, req resource.SchemaRequest, r stringvalidator.ConflictsWith(path.Expressions{ path.MatchRoot("relation_to_netflow_monitor_policies"), }...), + MakeStringRequired(), }, }, "tn_netflow_monitor_pol_name": schema.StringAttribute{ @@ -4838,6 +4912,7 @@ func (r *FvBDResource) Schema(ctx context.Context, req resource.SchemaRequest, r stringvalidator.ConflictsWith(path.Expressions{ path.MatchRoot("relation_to_netflow_monitor_policies"), }...), + MakeStringRequired(), }, }, }, diff --git a/internal/provider/resource_aci_bridge_domain_test.go b/internal/provider/resource_aci_bridge_domain_test.go index b68388303..92ebe53d5 100644 --- a/internal/provider/resource_aci_bridge_domain_test.go +++ b/internal/provider/resource_aci_bridge_domain_test.go @@ -928,10 +928,80 @@ func TestAccResourceFvBDWithFvTenant(t *testing.T) { ), }, }, + // Update with legacy attribute config + { + Config: testConfigFvBDLegacyAttributesWithFvTenant + testConfigDataSourceSystem, + ExpectNonEmptyPlan: false, + }, }, CheckDestroy: testCheckResourceDestroy, }) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t, "apic", "1.0(1e)-") }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create with legacy attribute config + { + Config: testConfigFvBDLegacyAttributesWithFvTenant + testConfigDataSourceSystem, + ExpectNonEmptyPlan: false, + }, + }, + CheckDestroy: testCheckResourceDestroy, + }) +} + +const testChildDependencyConfigFvBD = ` +resource "aci_monitoring_policy" "test_monitoring_policy_0"{ + tenant_dn = aci_tenant.test.id + name = "monitoring_policy_name_1" +} +resource "aci_first_hop_security_policy" "test_first_hop_security_policy_1"{ + parent_dn = aci_tenant.test.id + name = "first_hop_security_policy_name_1" +} +resource "aci_neighbor_discovery_interface_policy" "test_neighbor_discovery_interface_policy_0"{ + parent_dn = aci_tenant.test.id + name = "neighbor_discovery_interface_policy_name_1" } +resource "aci_netflow_monitor_policy" "test_netflow_monitor_policy_1"{ + parent_dn = aci_tenant.test.id + name = "netflow_monitor_policy_name_1" +} +resource "aci_vrf" "test_vrf_0"{ + tenant_dn = aci_tenant.test.id + name = "vrf_name_1" +} +resource "aci_l3_outside" "test_l3_outside_1"{ + tenant_dn = aci_tenant.test.id + name = "l3_outside_name_1" + relation_l3ext_rs_ectx = aci_vrf.test_vrf_0.id +} +resource "aci_l3_outside" "test_l3_outside_0"{ + tenant_dn = aci_tenant.test.id + name = "l3_outside_name_0" + relation_l3ext_rs_ectx = aci_vrf.test_vrf_0.id +} +resource "aci_route_control_profile" "test_route_control_profile_1"{ + parent_dn = aci_l3_outside.test_l3_outside_0.id + name = "route_control_profile_name_1" +} +resource "aci_dhcp_relay_policy" "test_dhcp_relay_policy_0"{ + tenant_dn = aci_tenant.test.id + name = "dhcp_relay_policy_name_1" +} +resource "aci_end_point_retention_policy" "test_end_point_retention_policy_1"{ + tenant_dn = aci_tenant.test.id + name = "end_point_retention_policy_name_1" +} +resource "aci_igmp_snooping_policy" "test_igmp_snooping_policy_0"{ + parent_dn = aci_tenant.test.id + name = "igmp_snooping_policy_name_1" +} +resource "aci_mld_snooping_policy" "test_mld_snooping_policy_1"{ + parent_dn = aci_tenant.test.id + name = "mld_snooping_policy_name_1" +} +` const testConfigFvBDMinDependencyWithFvTenantAllowExisting = testConfigFvTenantMin + ` resource "aci_bridge_domain" "allow_test" { @@ -1019,7 +1089,7 @@ resource "aci_bridge_domain" "test" { virtual_mac_address = "not-applicable" } ` -const testConfigFvBDChildrenDependencyWithFvTenant = testConfigFvTenantMin + ` +const testConfigFvBDChildrenDependencyWithFvTenant = testChildDependencyConfigFvBD + testConfigFvTenantMin + ` resource "aci_bridge_domain" "test" { parent_dn = aci_tenant.test.id name = "test_name" @@ -1084,7 +1154,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - dhcp_relay_policy_name = "dhcp_relay_policy_name_1" + dhcp_relay_policy_name = aci_dhcp_relay_policy.test_dhcp_relay_policy_0.name } relation_to_end_point_retention_policy = { annotation = "annotation_1" @@ -1108,7 +1178,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - end_point_retention_policy_name = "end_point_retention_policy_name_1" + end_point_retention_policy_name = aci_end_point_retention_policy.test_end_point_retention_policy_1.name resolve_action = "inherit" } relation_to_first_hop_security_policy = { @@ -1133,7 +1203,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - first_hop_security_policy_name = "first_hop_security_policy_name_1" + first_hop_security_policy_name = aci_first_hop_security_policy.test_first_hop_security_policy_1.name } relation_to_igmp_snooping_policy = { annotation = "annotation_1" @@ -1157,7 +1227,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - igmp_snooping_policy_name = "igmp_snooping_policy_name_1" + igmp_snooping_policy_name = aci_igmp_snooping_policy.test_igmp_snooping_policy_0.name } relation_to_l3_outsides = [ { @@ -1182,7 +1252,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - l3_outside_name = "l3_outside_name_0" + l3_outside_name = aci_l3_outside.test_l3_outside_0.name }, { annotation = "annotation_2" @@ -1206,7 +1276,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - l3_outside_name = "l3_outside_name_1" + l3_outside_name = aci_l3_outside.test_l3_outside_1.name }, ] relation_to_mld_snooping_policy = { @@ -1231,7 +1301,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - mld_snooping_policy_name = "mld_snooping_policy_name_1" + mld_snooping_policy_name = aci_mld_snooping_policy.test_mld_snooping_policy_1.name } relation_to_monitor_policy = { annotation = "annotation_1" @@ -1255,7 +1325,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - monitoring_policy_name = "monitoring_policy_name_1" + monitoring_policy_name = aci_monitoring_policy.test_monitoring_policy_0.name } relation_to_neighbor_discovery_interface_policy = { annotation = "annotation_1" @@ -1279,7 +1349,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - neighbor_discovery_interface_policy_name = "neighbor_discovery_interface_policy_name_1" + neighbor_discovery_interface_policy_name = aci_neighbor_discovery_interface_policy.test_neighbor_discovery_interface_policy_0.name } relation_to_netflow_monitor_policies = [ { @@ -1330,7 +1400,7 @@ resource "aci_bridge_domain" "test" { }, ] filter_type = "ipv4" - netflow_monitor_policy_name = "netflow_monitor_policy_name_1" + netflow_monitor_policy_name = aci_netflow_monitor_policy.test_netflow_monitor_policy_1.name }, ] relation_to_route_control_profile = { @@ -1355,8 +1425,8 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - l3_outside_name = "l3_outside_name_1" - route_control_profile_name = "route_control_profile_name_1" + l3_outside_name = aci_l3_outside.test_l3_outside_1.name + route_control_profile_name = aci_route_control_profile.test_route_control_profile_1.name } relation_to_vrf = { annotation = "annotation_1" @@ -1380,7 +1450,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - vrf_name = "vrf_name_1" + vrf_name = aci_vrf.test_vrf_0.name } rogue_coop_exceptions = [ { @@ -1451,14 +1521,14 @@ resource "aci_bridge_domain" "test" { } ` -const testConfigFvBDChildrenRemoveFromConfigDependencyWithFvTenant = testConfigFvTenantMin + ` +const testConfigFvBDChildrenRemoveFromConfigDependencyWithFvTenant = testChildDependencyConfigFvBD + testConfigFvTenantMin + ` resource "aci_bridge_domain" "test" { parent_dn = aci_tenant.test.id name = "test_name" } ` -const testConfigFvBDChildrenRemoveOneDependencyWithFvTenant = testConfigFvTenantMin + ` +const testConfigFvBDChildrenRemoveOneDependencyWithFvTenant = testChildDependencyConfigFvBD + testConfigFvTenantMin + ` resource "aci_bridge_domain" "test" { parent_dn = aci_tenant.test.id name = "test_name" @@ -1484,7 +1554,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - end_point_retention_policy_name = "end_point_retention_policy_name_1" + end_point_retention_policy_name = aci_end_point_retention_policy.test_end_point_retention_policy_1.name resolve_action = "inherit" } relation_to_first_hop_security_policy = {} @@ -1502,7 +1572,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - igmp_snooping_policy_name = "igmp_snooping_policy_name_1" + igmp_snooping_policy_name = aci_igmp_snooping_policy.test_igmp_snooping_policy_0.name } relation_to_l3_outsides = [ { @@ -1519,7 +1589,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - l3_outside_name = "l3_outside_name_1" + l3_outside_name = aci_l3_outside.test_l3_outside_1.name }, ] relation_to_mld_snooping_policy = { @@ -1536,7 +1606,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - mld_snooping_policy_name = "mld_snooping_policy_name_1" + mld_snooping_policy_name = aci_mld_snooping_policy.test_mld_snooping_policy_1.name } relation_to_monitor_policy = {} relation_to_neighbor_discovery_interface_policy = { @@ -1553,7 +1623,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - neighbor_discovery_interface_policy_name = "neighbor_discovery_interface_policy_name_1" + neighbor_discovery_interface_policy_name = aci_neighbor_discovery_interface_policy.test_neighbor_discovery_interface_policy_0.name } relation_to_netflow_monitor_policies = [ { @@ -1571,7 +1641,7 @@ resource "aci_bridge_domain" "test" { }, ] filter_type = "ipv4" - netflow_monitor_policy_name = "netflow_monitor_policy_name_1" + netflow_monitor_policy_name = aci_netflow_monitor_policy.test_netflow_monitor_policy_1.name }, ] relation_to_route_control_profile = {} @@ -1589,7 +1659,7 @@ resource "aci_bridge_domain" "test" { value = "test_value" }, ] - vrf_name = "vrf_name_1" + vrf_name = aci_vrf.test_vrf_0.name } rogue_coop_exceptions = [ { @@ -1621,7 +1691,7 @@ resource "aci_bridge_domain" "test" { } ` -const testConfigFvBDChildrenRemoveAllDependencyWithFvTenant = testConfigFvTenantMin + ` +const testConfigFvBDChildrenRemoveAllDependencyWithFvTenant = testChildDependencyConfigFvBD + testConfigFvTenantMin + ` resource "aci_bridge_domain" "test" { parent_dn = aci_tenant.test.id name = "test_name" @@ -1632,7 +1702,7 @@ resource "aci_bridge_domain" "test" { annotation = "annotation_1" annotations = [] tags = [] - end_point_retention_policy_name = "end_point_retention_policy_name_1" + end_point_retention_policy_name = aci_end_point_retention_policy.test_end_point_retention_policy_1.name resolve_action = "inherit" } relation_to_first_hop_security_policy = {} @@ -1640,21 +1710,21 @@ resource "aci_bridge_domain" "test" { annotation = "annotation_1" annotations = [] tags = [] - igmp_snooping_policy_name = "igmp_snooping_policy_name_1" + igmp_snooping_policy_name = aci_igmp_snooping_policy.test_igmp_snooping_policy_0.name } relation_to_l3_outsides = [] relation_to_mld_snooping_policy = { annotation = "annotation_1" annotations = [] tags = [] - mld_snooping_policy_name = "mld_snooping_policy_name_1" + mld_snooping_policy_name = aci_mld_snooping_policy.test_mld_snooping_policy_1.name } relation_to_monitor_policy = {} relation_to_neighbor_discovery_interface_policy = { annotation = "annotation_1" annotations = [] tags = [] - neighbor_discovery_interface_policy_name = "neighbor_discovery_interface_policy_name_1" + neighbor_discovery_interface_policy_name = aci_neighbor_discovery_interface_policy.test_neighbor_discovery_interface_policy_0.name } relation_to_netflow_monitor_policies = [] relation_to_route_control_profile = {} @@ -1662,9 +1732,44 @@ resource "aci_bridge_domain" "test" { annotation = "annotation_1" annotations = [] tags = [] - vrf_name = "vrf_name_1" + vrf_name = aci_vrf.test_vrf_0.name } rogue_coop_exceptions = [] tags = [] } ` + +const testConfigFvBDLegacyAttributesWithFvTenant = testChildDependencyConfigFvBD + testConfigFvTenantMin + ` +resource "aci_bridge_domain" "test" { + name = "test_name" + arp_flood = "no" + ep_clear = "no" + ep_move_detect_mode = "garp" + host_based_routing = "no" + intersite_bum_traffic_allow = "no" + ipv6_mcast_allow = "no" + ll_addr = "fe80::1" + mac = "00:22:BD:F8:19:FE" + mcast_allow = "no" + multi_dst_pkt_act = "bd-flood" + relation_fv_rs_abd_pol_mon_pol = aci_monitoring_policy.test_monitoring_policy_0.id + relation_fv_rs_bd_to_ep_ret = aci_end_point_retention_policy.test_end_point_retention_policy_1.id + relation_fv_rs_bd_to_fhs = aci_first_hop_security_policy.test_first_hop_security_policy_1.id + relation_fv_rs_bd_to_nd_p = aci_neighbor_discovery_interface_policy.test_neighbor_discovery_interface_policy_0.id + relation_fv_rs_bd_to_out = [aci_l3_outside.test_l3_outside_1.id] + relation_fv_rs_bd_to_relay_p = aci_dhcp_relay_policy.test_dhcp_relay_policy_0.id + relation_fv_rs_ctx = aci_vrf.test_vrf_0.id + relation_fv_rs_igmpsn = aci_igmp_snooping_policy.test_igmp_snooping_policy_0.id + relation_fv_rs_mldsn = aci_mld_snooping_policy.test_mld_snooping_policy_1.id + tenant_dn = aci_tenant.test.id + unicast_route = "yes" + unk_mac_ucast_act = "flood" + unk_mcast_act = "flood" + v6unk_mcast_act = "flood" + vmac = "00:22:BD:F8:19:FB" + relation_fv_rs_bd_to_netflow_monitor_pol { + flt_type = "ce" + tn_netflow_monitor_pol_name = aci_netflow_monitor_policy.test_netflow_monitor_policy_1.id + } +} +` diff --git a/internal/provider/resource_aci_certificate_authority.go b/internal/provider/resource_aci_certificate_authority.go index d1a24fbd2..e849a49b5 100644 --- a/internal/provider/resource_aci_certificate_authority.go +++ b/internal/provider/resource_aci_certificate_authority.go @@ -208,7 +208,7 @@ func (r *PkiTPResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(nil), }, Validators: []validator.Set{ setvalidator.SizeAtMost(2), diff --git a/internal/provider/resource_aci_custom_qos_policy.go b/internal/provider/resource_aci_custom_qos_policy.go index 88bb6cdc9..6bbf75f1d 100644 --- a/internal/provider/resource_aci_custom_qos_policy.go +++ b/internal/provider/resource_aci_custom_qos_policy.go @@ -170,6 +170,63 @@ var QosDot1PClassQosCustomPolType = types.ObjectType{ }, } +func QosDot1PClassQosCustomPolSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []QosDot1PClassQosCustomPolResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.Descr.IsNull() { + nullInStateFound = true + planSetValues[index].Descr = basetypes.NewStringNull() + } + if stateValue.From.IsNull() { + nullInStateFound = true + planSetValues[index].From = customTypes.NewQosDot1PClassFromStringNull() + } + if stateValue.Name.IsNull() { + nullInStateFound = true + planSetValues[index].Name = basetypes.NewStringNull() + } + if stateValue.NameAlias.IsNull() { + nullInStateFound = true + planSetValues[index].NameAlias = basetypes.NewStringNull() + } + if stateValue.Prio.IsNull() { + nullInStateFound = true + planSetValues[index].Prio = customTypes.NewQosDot1PClassPrioStringNull() + } + if stateValue.Target.IsNull() { + nullInStateFound = true + planSetValues[index].Target = customTypes.NewQosDot1PClassTargetStringNull() + } + if stateValue.TargetCos.IsNull() { + nullInStateFound = true + planSetValues[index].TargetCos = customTypes.NewQosDot1PClassTargetCosStringNull() + } + if stateValue.To.IsNull() { + nullInStateFound = true + planSetValues[index].To = customTypes.NewQosDot1PClassToStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, QosDot1PClassQosCustomPolType, planSetValues) + return planSet + +} + // TagAnnotationQosDot1PClassQosCustomPolResourceModel describes the resource data model for the children without relation ships. type TagAnnotationQosDot1PClassQosCustomPolResourceModel struct { Key types.String `tfsdk:"key"` @@ -267,6 +324,63 @@ var QosDscpClassQosCustomPolType = types.ObjectType{ }, } +func QosDscpClassQosCustomPolSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []QosDscpClassQosCustomPolResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.Descr.IsNull() { + nullInStateFound = true + planSetValues[index].Descr = basetypes.NewStringNull() + } + if stateValue.From.IsNull() { + nullInStateFound = true + planSetValues[index].From = customTypes.NewQosDscpClassFromStringNull() + } + if stateValue.Name.IsNull() { + nullInStateFound = true + planSetValues[index].Name = basetypes.NewStringNull() + } + if stateValue.NameAlias.IsNull() { + nullInStateFound = true + planSetValues[index].NameAlias = basetypes.NewStringNull() + } + if stateValue.Prio.IsNull() { + nullInStateFound = true + planSetValues[index].Prio = customTypes.NewQosDscpClassPrioStringNull() + } + if stateValue.Target.IsNull() { + nullInStateFound = true + planSetValues[index].Target = customTypes.NewQosDscpClassTargetStringNull() + } + if stateValue.TargetCos.IsNull() { + nullInStateFound = true + planSetValues[index].TargetCos = customTypes.NewQosDscpClassTargetCosStringNull() + } + if stateValue.To.IsNull() { + nullInStateFound = true + planSetValues[index].To = customTypes.NewQosDscpClassToStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, QosDscpClassQosCustomPolType, planSetValues) + return planSet + +} + // TagAnnotationQosDscpClassQosCustomPolResourceModel describes the resource data model for the children without relation ships. type TagAnnotationQosDscpClassQosCustomPolResourceModel struct { Key types.String `tfsdk:"key"` @@ -465,6 +579,7 @@ func (r *QosCustomPolResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(QosDot1PClassQosCustomPolSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -634,6 +749,7 @@ func (r *QosCustomPolResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(QosDscpClassQosCustomPolSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ diff --git a/internal/provider/resource_aci_endpoint_security_group.go b/internal/provider/resource_aci_endpoint_security_group.go index ece943402..5d11fefc2 100644 --- a/internal/provider/resource_aci_endpoint_security_group.go +++ b/internal/provider/resource_aci_endpoint_security_group.go @@ -212,6 +212,39 @@ var FvRsConsFvESgType = types.ObjectType{ }, } +func FvRsConsFvESgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsConsFvESgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.Prio.IsNull() { + nullInStateFound = true + planSetValues[index].Prio = customTypes.NewFvRsConsPrioStringNull() + } + if stateValue.TnVzBrCPName.IsNull() { + nullInStateFound = true + planSetValues[index].TnVzBrCPName = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsConsFvESgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsConsFvESgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsConsFvESgResourceModel struct { Key types.String `tfsdk:"key"` @@ -291,6 +324,39 @@ var FvRsConsIfFvESgType = types.ObjectType{ }, } +func FvRsConsIfFvESgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsConsIfFvESgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.Prio.IsNull() { + nullInStateFound = true + planSetValues[index].Prio = customTypes.NewFvRsConsIfPrioStringNull() + } + if stateValue.TnVzCPIfName.IsNull() { + nullInStateFound = true + planSetValues[index].TnVzCPIfName = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsConsIfFvESgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsConsIfFvESgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsConsIfFvESgResourceModel struct { Key types.String `tfsdk:"key"` @@ -367,6 +433,35 @@ var FvRsIntraEpgFvESgType = types.ObjectType{ }, } +func FvRsIntraEpgFvESgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsIntraEpgFvESgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.TnVzBrCPName.IsNull() { + nullInStateFound = true + planSetValues[index].TnVzBrCPName = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsIntraEpgFvESgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsIntraEpgFvESgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsIntraEpgFvESgResourceModel struct { Key types.String `tfsdk:"key"` @@ -449,6 +544,43 @@ var FvRsProvFvESgType = types.ObjectType{ }, } +func FvRsProvFvESgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsProvFvESgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.MatchT.IsNull() { + nullInStateFound = true + planSetValues[index].MatchT = basetypes.NewStringNull() + } + if stateValue.Prio.IsNull() { + nullInStateFound = true + planSetValues[index].Prio = customTypes.NewFvRsProvPrioStringNull() + } + if stateValue.TnVzBrCPName.IsNull() { + nullInStateFound = true + planSetValues[index].TnVzBrCPName = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsProvFvESgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsProvFvESgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsProvFvESgResourceModel struct { Key types.String `tfsdk:"key"` @@ -599,6 +731,35 @@ var FvRsSecInheritedFvESgType = types.ObjectType{ }, } +func FvRsSecInheritedFvESgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvRsSecInheritedFvESgResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.TDn.IsNull() { + nullInStateFound = true + planSetValues[index].TDn = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvRsSecInheritedFvESgType, planSetValues) + return planSet + +} + // TagAnnotationFvRsSecInheritedFvESgResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvRsSecInheritedFvESgResourceModel struct { Key types.String `tfsdk:"key"` @@ -730,17 +891,39 @@ type FvRsConsFvESgResourceModelV1 struct { Prio types.String `tfsdk:"prio"` } +func getEmptyFvRsConsFvESgResourceModelV1() FvRsConsFvESgResourceModelV1 { + return FvRsConsFvESgResourceModelV1{ + TargetDn: basetypes.NewStringNull(), + Prio: basetypes.NewStringNull(), + } +} + type FvRsConsIfFvESgResourceModelV1 struct { TargetDn types.String `tfsdk:"target_dn"` Prio types.String `tfsdk:"prio"` } +func getEmptyFvRsConsIfFvESgResourceModelV1() FvRsConsIfFvESgResourceModelV1 { + return FvRsConsIfFvESgResourceModelV1{ + TargetDn: basetypes.NewStringNull(), + Prio: basetypes.NewStringNull(), + } +} + type FvRsProvFvESgResourceModelV1 struct { TargetDn types.String `tfsdk:"target_dn"` MatchT types.String `tfsdk:"match_t"` Prio types.String `tfsdk:"prio"` } +func getEmptyFvRsProvFvESgResourceModelV1() FvRsProvFvESgResourceModelV1 { + return FvRsProvFvESgResourceModelV1{ + TargetDn: basetypes.NewStringNull(), + MatchT: basetypes.NewStringNull(), + Prio: basetypes.NewStringNull(), + } +} + func (r *FvESgResource) UpgradeState(ctx context.Context) map[int64]resource.StateUpgrader { return map[int64]resource.StateUpgrader{ 1: { @@ -1128,7 +1311,10 @@ func setFvESgLegacyAttributes(ctx context.Context, diags *diag.Diagnostics, data data.DeprecatedPrefGrMemb = basetypes.NewStringValue(attributeValue.(string)) } } + DeprecatedFvRsConsFvESgList := make([]FvRsConsFvESgResourceModelV1, 0) + DeprecatedFvRsConsIfFvESgList := make([]FvRsConsIfFvESgResourceModelV1, 0) DeprecatedFvRsIntraEpgFvESgList := make([]string, 0) + DeprecatedFvRsProvFvESgList := make([]FvRsProvFvESgResourceModelV1, 0) data.DeprecatedFvRsScope = basetypes.NewStringNull() DeprecatedFvRsSecInheritedFvESgList := make([]string, 0) @@ -1138,6 +1324,30 @@ func setFvESgLegacyAttributes(ctx context.Context, diags *diag.Diagnostics, data for _, child := range children { for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) + if childClassName == "fvRsCons" { + DeprecatedFvRsConsFvESg := getEmptyFvRsConsFvESgResourceModelV1() + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "prio" { + DeprecatedFvRsConsFvESg.Prio = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "tDn" { + DeprecatedFvRsConsFvESg.TargetDn = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + DeprecatedFvRsConsFvESgList = append(DeprecatedFvRsConsFvESgList, DeprecatedFvRsConsFvESg) + } + if childClassName == "fvRsConsIf" { + DeprecatedFvRsConsIfFvESg := getEmptyFvRsConsIfFvESgResourceModelV1() + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "prio" { + DeprecatedFvRsConsIfFvESg.Prio = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "tDn" { + DeprecatedFvRsConsIfFvESg.TargetDn = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + DeprecatedFvRsConsIfFvESgList = append(DeprecatedFvRsConsIfFvESgList, DeprecatedFvRsConsIfFvESg) + } if childClassName == "fvRsIntraEpg" { for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "tDn" && childAttributeValue != "" && !ContainsString(DeprecatedFvRsIntraEpgFvESgList, childAttributeValue.(string)) { @@ -1145,6 +1355,21 @@ func setFvESgLegacyAttributes(ctx context.Context, diags *diag.Diagnostics, data } } } + if childClassName == "fvRsProv" { + DeprecatedFvRsProvFvESg := getEmptyFvRsProvFvESgResourceModelV1() + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "matchT" { + DeprecatedFvRsProvFvESg.MatchT = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "prio" { + DeprecatedFvRsProvFvESg.Prio = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "tDn" { + DeprecatedFvRsProvFvESg.TargetDn = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + DeprecatedFvRsProvFvESgList = append(DeprecatedFvRsProvFvESgList, DeprecatedFvRsProvFvESg) + } if childClassName == "fvRsScope" { for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "tDn" { @@ -1161,11 +1386,14 @@ func setFvESgLegacyAttributes(ctx context.Context, diags *diag.Diagnostics, data } } } - data.DeprecatedFvRsCons = types.SetNull(deprecatedFvRsConsType) - data.DeprecatedFvRsConsIf = types.SetNull(deprecatedFvRsConsIfType) + fvRsConsSet, _ := types.SetValueFrom(ctx, data.DeprecatedFvRsCons.ElementType(ctx), DeprecatedFvRsConsFvESgList) + data.DeprecatedFvRsCons = fvRsConsSet + fvRsConsIfSet, _ := types.SetValueFrom(ctx, data.DeprecatedFvRsConsIf.ElementType(ctx), DeprecatedFvRsConsIfFvESgList) + data.DeprecatedFvRsConsIf = fvRsConsIfSet fvRsIntraEpgSet, _ := types.SetValueFrom(ctx, data.DeprecatedFvRsIntraEpg.ElementType(ctx), DeprecatedFvRsIntraEpgFvESgList) data.DeprecatedFvRsIntraEpg = fvRsIntraEpgSet - data.DeprecatedFvRsProv = types.SetNull(deprecatedFvRsProvType) + fvRsProvSet, _ := types.SetValueFrom(ctx, data.DeprecatedFvRsProv.ElementType(ctx), DeprecatedFvRsProvFvESgList) + data.DeprecatedFvRsProv = fvRsProvSet fvRsSecInheritedSet, _ := types.SetValueFrom(ctx, data.DeprecatedFvRsSecInherited.ElementType(ctx), DeprecatedFvRsSecInheritedFvESgList) data.DeprecatedFvRsSecInherited = fvRsSecInheritedSet } @@ -1199,65 +1427,27 @@ func (r *FvESgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanR } } - if !configData.MatchT.IsNull() { - planData.DeprecatedMatchT = configData.MatchT - } else if !configData.DeprecatedMatchT.IsNull() { + if !configData.DeprecatedMatchT.IsNull() { planData.MatchT = configData.DeprecatedMatchT - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedMatchT = stateData.DeprecatedMatchT } - if !configData.ParentDn.IsNull() { - planData.DeprecatedParentDn = configData.ParentDn - } else if !configData.DeprecatedParentDn.IsNull() { + if !configData.DeprecatedParentDn.IsNull() { planData.ParentDn = configData.DeprecatedParentDn - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedParentDn = stateData.DeprecatedParentDn } - if !configData.PcEnfPref.IsNull() { - planData.DeprecatedPcEnfPref = configData.PcEnfPref - } else if !configData.DeprecatedPcEnfPref.IsNull() { + if !configData.DeprecatedPcEnfPref.IsNull() { planData.PcEnfPref = configData.DeprecatedPcEnfPref - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedPcEnfPref = stateData.DeprecatedPcEnfPref } - if !configData.PrefGrMemb.IsNull() { - planData.DeprecatedPrefGrMemb = configData.PrefGrMemb - } else if !configData.DeprecatedPrefGrMemb.IsNull() { + if !configData.DeprecatedPrefGrMemb.IsNull() { planData.PrefGrMemb = configData.DeprecatedPrefGrMemb - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedPrefGrMemb = stateData.DeprecatedPrefGrMemb } - if !configData.FvRsSecInherited.IsNull() && stateData != nil { - var attributeValues []FvRsSecInheritedFvESgResourceModel - var newAttributeValues, stateAttributeValues []string - configData.FvRsSecInherited.ElementsAs(ctx, &attributeValues, false) - stateData.DeprecatedFvRsSecInherited.ElementsAs(ctx, &stateAttributeValues, false) - for _, attributeValue := range attributeValues { - newAttributeValues = append(newAttributeValues, attributeValue.TDn.ValueString()) - } - - if len(newAttributeValues) == len(stateAttributeValues) { - allMatchState := true - for _, stateAttributeValue := range stateAttributeValues { - if !ContainsString(newAttributeValues, GetMOName(stateAttributeValue)) { - allMatchState = false - break - } - } - if allMatchState { - FvRsSecInheritedSet, _ := types.SetValueFrom(ctx, basetypes.StringType{}, stateAttributeValues) - planData.DeprecatedFvRsSecInherited = FvRsSecInheritedSet - } - } - } else if !configData.DeprecatedFvRsSecInherited.IsNull() { + if !configData.DeprecatedFvRsSecInherited.IsNull() { FvRsSecInheritedList := make([]FvRsSecInheritedFvESgResourceModel, 0) var attributeValues []basetypes.StringValue var newAttributeValues []FvRsSecInheritedFvESgResourceModel - configData.DeprecatedFvRsSecInherited.ElementsAs(ctx, &attributeValues, false) + planData.DeprecatedFvRsSecInherited.ElementsAs(ctx, &attributeValues, false) if stateData != nil { stateData.FvRsSecInherited.ElementsAs(ctx, &newAttributeValues, false) } @@ -1292,37 +1482,13 @@ func (r *FvESgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanR } FvRsSecInheritedSet, _ := types.SetValueFrom(ctx, FvRsSecInheritedFvESgType, FvRsSecInheritedList) planData.FvRsSecInherited = FvRsSecInheritedSet - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsSecInherited = stateData.DeprecatedFvRsSecInherited } - if !configData.FvRsIntraEpg.IsNull() && stateData != nil { - var attributeValues []FvRsIntraEpgFvESgResourceModel - var newAttributeValues, stateAttributeValues []string - configData.FvRsIntraEpg.ElementsAs(ctx, &attributeValues, false) - stateData.DeprecatedFvRsIntraEpg.ElementsAs(ctx, &stateAttributeValues, false) - for _, attributeValue := range attributeValues { - newAttributeValues = append(newAttributeValues, attributeValue.TnVzBrCPName.ValueString()) - } - - if len(newAttributeValues) == len(stateAttributeValues) { - allMatchState := true - for _, stateAttributeValue := range stateAttributeValues { - if !ContainsString(newAttributeValues, GetMOName(stateAttributeValue)) { - allMatchState = false - break - } - } - if allMatchState { - FvRsIntraEpgSet, _ := types.SetValueFrom(ctx, basetypes.StringType{}, stateAttributeValues) - planData.DeprecatedFvRsIntraEpg = FvRsIntraEpgSet - } - } - } else if !configData.DeprecatedFvRsIntraEpg.IsNull() { + if !configData.DeprecatedFvRsIntraEpg.IsNull() { FvRsIntraEpgList := make([]FvRsIntraEpgFvESgResourceModel, 0) var attributeValues []basetypes.StringValue var newAttributeValues []FvRsIntraEpgFvESgResourceModel - configData.DeprecatedFvRsIntraEpg.ElementsAs(ctx, &attributeValues, false) + planData.DeprecatedFvRsIntraEpg.ElementsAs(ctx, &attributeValues, false) if stateData != nil { stateData.FvRsIntraEpg.ElementsAs(ctx, &newAttributeValues, false) } @@ -1357,27 +1523,14 @@ func (r *FvESgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanR } FvRsIntraEpgSet, _ := types.SetValueFrom(ctx, FvRsIntraEpgFvESgType, FvRsIntraEpgList) planData.FvRsIntraEpg = FvRsIntraEpgSet - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsIntraEpg = stateData.DeprecatedFvRsIntraEpg } - if !configData.FvRsScope.IsNull() && stateData != nil { - if IsEmptySingleNestedAttribute(configData.FvRsScope.Attributes()) { - planData.FvRsScope = configData.FvRsScope - planData.DeprecatedFvRsScope = basetypes.NewStringNull() - } else { - var attributeValues FvRsScopeFvESgResourceModel - configData.FvRsScope.As(ctx, &attributeValues, basetypes.ObjectAsOptions{}) - if GetMOName(stateData.DeprecatedFvRsScope.ValueString()) == attributeValues.TnFvCtxName.ValueString() && !attributeValues.TnFvCtxName.IsNull() { - planData.DeprecatedFvRsScope = stateData.DeprecatedFvRsScope - } - } - } else if !configData.DeprecatedFvRsScope.IsNull() { + if !configData.DeprecatedFvRsScope.IsNull() { var newAttributeValues FvRsScopeFvESgResourceModel tagAnnotationFvRsScopeFvESgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsScopeFvESgType, make([]TagAnnotationFvRsScopeFvESgResourceModel, 0)) tagTagFvRsScopeFvESgValue, _ := types.SetValueFrom(ctx, TagTagFvRsScopeFvESgType, make([]TagTagFvRsScopeFvESgResourceModel, 0)) annotationValue := planData.Annotation - if stateData != nil { + if stateData != nil && !IsEmptySingleNestedAttribute(stateData.FvRsScope.Attributes()) { stateData.FvRsScope.As(ctx, &newAttributeValues, basetypes.ObjectAsOptions{}) annotationValue = newAttributeValues.Annotation tagAnnotationFvRsScopeFvESgValue = newAttributeValues.TagAnnotation @@ -1395,23 +1548,16 @@ func (r *FvESgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanR } FvRsScopeObject, _ := types.ObjectValueFrom(ctx, FvRsScopeFvESgType, FvRsScope) planData.FvRsScope = FvRsScopeObject - } else if stateData != nil { // used to replace use state for unknown - planData.DeprecatedFvRsScope = stateData.DeprecatedFvRsScope } - planData.DeprecatedFvRsCons = types.SetNull(deprecatedFvRsConsType) if !configData.DeprecatedFvRsCons.IsNull() { FvRsConsList := make([]FvRsConsFvESgResourceModel, 0) var attributeValues []FvRsConsFvESgResourceModelV1 var newAttributeValues []FvRsConsFvESgResourceModel - configData.DeprecatedFvRsCons.ElementsAs(ctx, &attributeValues, false) - annotationValue := planData.Annotation if stateData != nil { stateData.FvRsCons.ElementsAs(ctx, &newAttributeValues, false) - for _, newAttributeValue := range newAttributeValues { - annotationValue = newAttributeValue.Annotation - } } + planData.DeprecatedFvRsCons.ElementsAs(ctx, &attributeValues, false) for _, attributeValue := range attributeValues { plannedFvRsCons := FvRsConsFvESgResourceModel{} foundAttributeValue := false @@ -1426,17 +1572,18 @@ func (r *FvESgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanR if !attributeValue.TargetDn.IsUnknown() { tnVzBrCPNameValue = basetypes.NewStringValue(GetMOName(attributeValue.TargetDn.ValueString())) } - FvRsCons := FvRsConsFvESgResourceModel{ - Annotation: annotationValue, - Prio: customTypes.FvRsConsPrioStringValue{StringValue: attributeValue.Prio}, + Annotation: planData.Annotation, TnVzBrCPName: tnVzBrCPNameValue, } - + if !attributeValue.Prio.IsNull() { + FvRsCons.Prio = customTypes.FvRsConsPrioStringValue{StringValue: attributeValue.Prio} + } else { + FvRsCons.Prio = customTypes.FvRsConsPrioStringValue{StringValue: basetypes.NewStringUnknown()} + } if foundAttributeValue { FvRsCons.TnVzBrCPName = plannedFvRsCons.TnVzBrCPName - } else { - FvRsCons.TnVzBrCPName = tnVzBrCPNameValue + FvRsCons.Annotation = plannedFvRsCons.Annotation } tagAnnotationFvRsConsFvESgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsConsFvESgType, make([]TagAnnotationFvRsConsFvESgResourceModel, 0)) FvRsCons.TagAnnotation = tagAnnotationFvRsConsFvESgValue @@ -1444,24 +1591,20 @@ func (r *FvESgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanR FvRsCons.TagTag = tagTagFvRsConsFvESgValue FvRsConsList = append(FvRsConsList, FvRsCons) } - FvRsConsSet, _ := types.SetValueFrom(ctx, FvRsConsFvESgType, FvRsConsList) planData.FvRsCons = FvRsConsSet + } else if !configData.FvRsCons.IsNull() && stateData == nil { + setUnknownDeprecatedFvRsConsFvESgResourceModelToPlan(ctx, planData) } - planData.DeprecatedFvRsConsIf = types.SetNull(deprecatedFvRsConsIfType) if !configData.DeprecatedFvRsConsIf.IsNull() { FvRsConsIfList := make([]FvRsConsIfFvESgResourceModel, 0) var attributeValues []FvRsConsIfFvESgResourceModelV1 var newAttributeValues []FvRsConsIfFvESgResourceModel - configData.DeprecatedFvRsConsIf.ElementsAs(ctx, &attributeValues, false) - annotationValue := planData.Annotation if stateData != nil { stateData.FvRsConsIf.ElementsAs(ctx, &newAttributeValues, false) - for _, newAttributeValue := range newAttributeValues { - annotationValue = newAttributeValue.Annotation - } } + planData.DeprecatedFvRsConsIf.ElementsAs(ctx, &attributeValues, false) for _, attributeValue := range attributeValues { plannedFvRsConsIf := FvRsConsIfFvESgResourceModel{} foundAttributeValue := false @@ -1476,17 +1619,18 @@ func (r *FvESgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanR if !attributeValue.TargetDn.IsUnknown() { tnVzCPIfNameValue = basetypes.NewStringValue(GetMOName(attributeValue.TargetDn.ValueString())) } - FvRsConsIf := FvRsConsIfFvESgResourceModel{ - Annotation: annotationValue, - Prio: customTypes.FvRsConsIfPrioStringValue{StringValue: attributeValue.Prio}, + Annotation: planData.Annotation, TnVzCPIfName: tnVzCPIfNameValue, } - + if !attributeValue.Prio.IsNull() { + FvRsConsIf.Prio = customTypes.FvRsConsIfPrioStringValue{StringValue: attributeValue.Prio} + } else { + FvRsConsIf.Prio = customTypes.FvRsConsIfPrioStringValue{StringValue: basetypes.NewStringUnknown()} + } if foundAttributeValue { FvRsConsIf.TnVzCPIfName = plannedFvRsConsIf.TnVzCPIfName - } else { - FvRsConsIf.TnVzCPIfName = tnVzCPIfNameValue + FvRsConsIf.Annotation = plannedFvRsConsIf.Annotation } tagAnnotationFvRsConsIfFvESgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsConsIfFvESgType, make([]TagAnnotationFvRsConsIfFvESgResourceModel, 0)) FvRsConsIf.TagAnnotation = tagAnnotationFvRsConsIfFvESgValue @@ -1494,24 +1638,20 @@ func (r *FvESgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanR FvRsConsIf.TagTag = tagTagFvRsConsIfFvESgValue FvRsConsIfList = append(FvRsConsIfList, FvRsConsIf) } - FvRsConsIfSet, _ := types.SetValueFrom(ctx, FvRsConsIfFvESgType, FvRsConsIfList) planData.FvRsConsIf = FvRsConsIfSet + } else if !configData.FvRsConsIf.IsNull() && stateData == nil { + setUnknownDeprecatedFvRsConsIfFvESgResourceModelToPlan(ctx, planData) } - planData.DeprecatedFvRsProv = types.SetNull(deprecatedFvRsProvType) if !configData.DeprecatedFvRsProv.IsNull() { FvRsProvList := make([]FvRsProvFvESgResourceModel, 0) var attributeValues []FvRsProvFvESgResourceModelV1 var newAttributeValues []FvRsProvFvESgResourceModel - configData.DeprecatedFvRsProv.ElementsAs(ctx, &attributeValues, false) - annotationValue := planData.Annotation if stateData != nil { stateData.FvRsProv.ElementsAs(ctx, &newAttributeValues, false) - for _, newAttributeValue := range newAttributeValues { - annotationValue = newAttributeValue.Annotation - } } + planData.DeprecatedFvRsProv.ElementsAs(ctx, &attributeValues, false) for _, attributeValue := range attributeValues { plannedFvRsProv := FvRsProvFvESgResourceModel{} foundAttributeValue := false @@ -1526,18 +1666,23 @@ func (r *FvESgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanR if !attributeValue.TargetDn.IsUnknown() { tnVzBrCPNameValue = basetypes.NewStringValue(GetMOName(attributeValue.TargetDn.ValueString())) } - FvRsProv := FvRsProvFvESgResourceModel{ - Annotation: annotationValue, - MatchT: attributeValue.MatchT, - Prio: customTypes.FvRsProvPrioStringValue{StringValue: attributeValue.Prio}, + Annotation: planData.Annotation, TnVzBrCPName: tnVzBrCPNameValue, } - + if !attributeValue.MatchT.IsNull() { + FvRsProv.MatchT = attributeValue.MatchT + } else { + FvRsProv.MatchT = basetypes.NewStringUnknown() + } + if !attributeValue.Prio.IsNull() { + FvRsProv.Prio = customTypes.FvRsProvPrioStringValue{StringValue: attributeValue.Prio} + } else { + FvRsProv.Prio = customTypes.FvRsProvPrioStringValue{StringValue: basetypes.NewStringUnknown()} + } if foundAttributeValue { FvRsProv.TnVzBrCPName = plannedFvRsProv.TnVzBrCPName - } else { - FvRsProv.TnVzBrCPName = tnVzBrCPNameValue + FvRsProv.Annotation = plannedFvRsProv.Annotation } tagAnnotationFvRsProvFvESgValue, _ := types.SetValueFrom(ctx, TagAnnotationFvRsProvFvESgType, make([]TagAnnotationFvRsProvFvESgResourceModel, 0)) FvRsProv.TagAnnotation = tagAnnotationFvRsProvFvESgValue @@ -1545,14 +1690,132 @@ func (r *FvESgResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanR FvRsProv.TagTag = tagTagFvRsProvFvESgValue FvRsProvList = append(FvRsProvList, FvRsProv) } - FvRsProvSet, _ := types.SetValueFrom(ctx, FvRsProvFvESgType, FvRsProvList) planData.FvRsProv = FvRsProvSet + } else if !configData.FvRsProv.IsNull() && stateData == nil { + setUnknownDeprecatedFvRsProvFvESgResourceModelToPlan(ctx, planData) + } + + // Workaround to compare the state with plan to avoid plan changes with only known after apply + if stateData != nil { + avoidFvESgPlanChangeForKnownAfterApplyOnly(ctx, planData, stateData, configData) } resp.Diagnostics.Append(resp.Plan.Set(ctx, &planData)...) } } +func setUnknownDeprecatedFvRsConsFvESgResourceModelToPlan(ctx context.Context, planData *FvESgResourceModel) { + var attributeValues []FvRsConsFvESgResourceModel + var legacyAttributeValues []FvRsConsFvESgResourceModelV1 + planData.FvRsCons.ElementsAs(ctx, &attributeValues, false) + for i := 0; i < len(attributeValues); i++ { + legacyAttributeValues = append(legacyAttributeValues, FvRsConsFvESgResourceModelV1{ + TargetDn: basetypes.NewStringUnknown(), + Prio: basetypes.NewStringUnknown(), + }) + } + DeprecatedFvRsConsSet, _ := types.SetValueFrom(ctx, deprecatedFvRsConsType, legacyAttributeValues) + planData.DeprecatedFvRsCons = DeprecatedFvRsConsSet +} +func setUnknownDeprecatedFvRsConsIfFvESgResourceModelToPlan(ctx context.Context, planData *FvESgResourceModel) { + var attributeValues []FvRsConsIfFvESgResourceModel + var legacyAttributeValues []FvRsConsIfFvESgResourceModelV1 + planData.FvRsConsIf.ElementsAs(ctx, &attributeValues, false) + for i := 0; i < len(attributeValues); i++ { + legacyAttributeValues = append(legacyAttributeValues, FvRsConsIfFvESgResourceModelV1{ + TargetDn: basetypes.NewStringUnknown(), + Prio: basetypes.NewStringUnknown(), + }) + } + DeprecatedFvRsConsIfSet, _ := types.SetValueFrom(ctx, deprecatedFvRsConsIfType, legacyAttributeValues) + planData.DeprecatedFvRsConsIf = DeprecatedFvRsConsIfSet +} +func setUnknownDeprecatedFvRsProvFvESgResourceModelToPlan(ctx context.Context, planData *FvESgResourceModel) { + var attributeValues []FvRsProvFvESgResourceModel + var legacyAttributeValues []FvRsProvFvESgResourceModelV1 + planData.FvRsProv.ElementsAs(ctx, &attributeValues, false) + for i := 0; i < len(attributeValues); i++ { + legacyAttributeValues = append(legacyAttributeValues, FvRsProvFvESgResourceModelV1{ + TargetDn: basetypes.NewStringUnknown(), + MatchT: basetypes.NewStringUnknown(), + Prio: basetypes.NewStringUnknown(), + }) + } + DeprecatedFvRsProvSet, _ := types.SetValueFrom(ctx, deprecatedFvRsProvType, legacyAttributeValues) + planData.DeprecatedFvRsProv = DeprecatedFvRsProvSet +} + +func avoidFvESgPlanChangeForKnownAfterApplyOnly(ctx context.Context, planData, stateData, configData *FvESgResourceModel) { + // Set read-only and deprecated attributes in planData from stateData + planData.PcTag = stateData.PcTag + planData.Scope = stateData.Scope + if configData.DeprecatedMatchT.IsNull() { + planData.DeprecatedMatchT = stateData.DeprecatedMatchT + } + if configData.DeprecatedParentDn.IsNull() { + planData.DeprecatedParentDn = stateData.DeprecatedParentDn + } + if configData.DeprecatedPcEnfPref.IsNull() { + planData.DeprecatedPcEnfPref = stateData.DeprecatedPcEnfPref + } + if configData.DeprecatedPrefGrMemb.IsNull() { + planData.DeprecatedPrefGrMemb = stateData.DeprecatedPrefGrMemb + } + if configData.DeprecatedFvRsSecInherited.IsNull() { + planData.DeprecatedFvRsSecInherited = stateData.DeprecatedFvRsSecInherited + } + if configData.DeprecatedFvRsIntraEpg.IsNull() { + planData.DeprecatedFvRsIntraEpg = stateData.DeprecatedFvRsIntraEpg + } + if configData.DeprecatedFvRsScope.IsNull() { + planData.DeprecatedFvRsScope = stateData.DeprecatedFvRsScope + } + if configData.DeprecatedFvRsCons.IsNull() { + planData.DeprecatedFvRsCons = stateData.DeprecatedFvRsCons + } + if configData.DeprecatedFvRsConsIf.IsNull() { + planData.DeprecatedFvRsConsIf = stateData.DeprecatedFvRsConsIf + } + if configData.DeprecatedFvRsProv.IsNull() { + planData.DeprecatedFvRsProv = stateData.DeprecatedFvRsProv + } + + // Compare the string representation of the planData and stateData because structs cannot be compared directly + if fmt.Sprintf("%s", planData) != fmt.Sprintf("%s", stateData) { + planData.PcTag = basetypes.NewStringUnknown() + planData.Scope = basetypes.NewStringUnknown() + if configData.DeprecatedMatchT.IsNull() { + planData.DeprecatedMatchT = basetypes.NewStringUnknown() + } + if configData.DeprecatedParentDn.IsNull() { + planData.DeprecatedParentDn = basetypes.NewStringUnknown() + } + if configData.DeprecatedPcEnfPref.IsNull() { + planData.DeprecatedPcEnfPref = basetypes.NewStringUnknown() + } + if configData.DeprecatedPrefGrMemb.IsNull() { + planData.DeprecatedPrefGrMemb = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsSecInherited.IsNull() { + planData.DeprecatedFvRsSecInherited = basetypes.NewSetUnknown(basetypes.StringType{}) + } + if configData.DeprecatedFvRsIntraEpg.IsNull() { + planData.DeprecatedFvRsIntraEpg = basetypes.NewSetUnknown(basetypes.StringType{}) + } + if configData.DeprecatedFvRsScope.IsNull() { + planData.DeprecatedFvRsScope = basetypes.NewStringUnknown() + } + if configData.DeprecatedFvRsCons.IsNull() { + setUnknownDeprecatedFvRsConsFvESgResourceModelToPlan(ctx, planData) + } + if configData.DeprecatedFvRsConsIf.IsNull() { + setUnknownDeprecatedFvRsConsIfFvESgResourceModelToPlan(ctx, planData) + } + if configData.DeprecatedFvRsProv.IsNull() { + setUnknownDeprecatedFvRsProvFvESgResourceModelToPlan(ctx, planData) + } + } +} func (r *FvESgResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { tflog.Debug(ctx, "Start metadata of resource: aci_endpoint_security_group") @@ -1615,6 +1878,7 @@ func (r *FvESgResource) Schema(ctx context.Context, req resource.SchemaRequest, DeprecationMessage: "Attribute `relation_fv_rs_cust_qos_pol` is deprecated. The attribute will be removed in the next major version of the provider.", PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, }, "relation_fv_rs_prot_by": schema.SetAttribute{ @@ -1721,12 +1985,16 @@ func (r *FvESgResource) Schema(ctx context.Context, req resource.SchemaRequest, MarkdownDescription: `The provider label match criteria.`, }, "name": schema.StringAttribute{ - Required: true, + Optional: true, + Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, + Validators: []validator.String{ + MakeStringRequired(), + }, MarkdownDescription: `The name of the Endpoint Security Group object.`, }, "name_alias": schema.StringAttribute{ @@ -1788,6 +2056,7 @@ func (r *FvESgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsConsFvESgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -1903,6 +2172,7 @@ func (r *FvESgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsConsIfFvESgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -2022,6 +2292,7 @@ func (r *FvESgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsIntraEpgFvESgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -2122,6 +2393,7 @@ func (r *FvESgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsProvFvESgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -2342,6 +2614,7 @@ func (r *FvESgResource) Schema(ctx context.Context, req resource.SchemaRequest, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvRsSecInheritedFvESgSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -2517,6 +2790,7 @@ func (r *FvESgResource) Schema(ctx context.Context, req resource.SchemaRequest, stringvalidator.ConflictsWith(path.Expressions{ path.MatchRoot("relation_to_consumed_contracts"), }...), + MakeStringRequired(), }, }, "prio": schema.StringAttribute{ @@ -2543,6 +2817,7 @@ func (r *FvESgResource) Schema(ctx context.Context, req resource.SchemaRequest, stringvalidator.ConflictsWith(path.Expressions{ path.MatchRoot("relation_to_imported_contracts"), }...), + MakeStringRequired(), }, }, "prio": schema.StringAttribute{ @@ -2569,6 +2844,7 @@ func (r *FvESgResource) Schema(ctx context.Context, req resource.SchemaRequest, stringvalidator.ConflictsWith(path.Expressions{ path.MatchRoot("relation_to_provided_contracts"), }...), + MakeStringRequired(), }, }, "match_t": schema.StringAttribute{ diff --git a/internal/provider/resource_aci_endpoint_security_group_test.go b/internal/provider/resource_aci_endpoint_security_group_test.go index 734522701..9a78a82c7 100644 --- a/internal/provider/resource_aci_endpoint_security_group_test.go +++ b/internal/provider/resource_aci_endpoint_security_group_test.go @@ -500,12 +500,53 @@ func TestAccResourceFvESgWithFvAp(t *testing.T) { resource.TestCheckResourceAttr("aci_endpoint_security_group.test", "tags.#", "0"), ), }, + // Update with legacy attribute config + { + Config: testConfigFvESgLegacyAttributesWithFvAp + testConfigDataSourceSystem, + ExpectNonEmptyPlan: false, + }, + }, + CheckDestroy: testCheckResourceDestroy, + }) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t, "apic", "1.0(1e)-") }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create with legacy attribute config + { + Config: testConfigFvESgLegacyAttributesWithFvAp + testConfigDataSourceSystem, + ExpectNonEmptyPlan: false, + }, }, CheckDestroy: testCheckResourceDestroy, }) } const testChildDependencyConfigFvESg = ` +resource "aci_contract" "test_contract_0"{ + tenant_dn = aci_tenant.test.id + name = "contract_name_0" +} +resource "aci_contract" "test_contract_1"{ + tenant_dn = aci_tenant.test.id + name = "contract_name_1" +} +resource "aci_imported_contract" "test_imported_contract_0"{ + tenant_dn = aci_tenant.test.id + name = "imported_contract_name_0" +} +resource "aci_imported_contract" "test_imported_contract_1"{ + tenant_dn = aci_tenant.test.id + name = "imported_contract_name_1" +} +resource "aci_vrf" "test_vrf_0"{ + tenant_dn = aci_tenant.test.id + name = "vrf_name_1" +} +resource "aci_vrf" "test_vrf_1"{ + tenant_dn = aci_tenant.test.id + name = "vrf_name_0" +} resource "aci_endpoint_security_group" "test_endpoint_security_group_0"{ application_profile_dn = aci_application_profile.test.id name = "esg_0" @@ -601,7 +642,7 @@ resource "aci_endpoint_security_group" "test" { value = "test_value" }, ] - contract_name = "contract_name_0" + contract_name = aci_contract.test_contract_0.name priority = "level1" }, { @@ -626,7 +667,7 @@ resource "aci_endpoint_security_group" "test" { value = "test_value" }, ] - contract_name = "contract_name_1" + contract_name = aci_contract.test_contract_1.name priority = "level2" }, ] @@ -703,7 +744,7 @@ resource "aci_endpoint_security_group" "test" { value = "test_value" }, ] - imported_contract_name = "imported_contract_name_0" + imported_contract_name = aci_imported_contract.test_imported_contract_0.name priority = "level1" }, { @@ -728,7 +769,7 @@ resource "aci_endpoint_security_group" "test" { value = "test_value" }, ] - imported_contract_name = "imported_contract_name_1" + imported_contract_name = aci_imported_contract.test_imported_contract_1.name priority = "level2" }, ] @@ -755,7 +796,7 @@ resource "aci_endpoint_security_group" "test" { value = "test_value" }, ] - contract_name = "contract_name_0" + contract_name = aci_contract.test_contract_0.name }, { annotation = "annotation_2" @@ -779,7 +820,7 @@ resource "aci_endpoint_security_group" "test" { value = "test_value" }, ] - contract_name = "contract_name_1" + contract_name = aci_contract.test_contract_1.name }, ] relation_to_provided_contracts = [ @@ -805,7 +846,7 @@ resource "aci_endpoint_security_group" "test" { value = "test_value" }, ] - contract_name = "contract_name_0" + contract_name = aci_contract.test_contract_0.name match_criteria = "All" priority = "level1" }, @@ -831,7 +872,7 @@ resource "aci_endpoint_security_group" "test" { value = "test_value" }, ] - contract_name = "contract_name_1" + contract_name = aci_contract.test_contract_1.name match_criteria = "AtleastOne" priority = "level2" }, @@ -858,7 +899,7 @@ resource "aci_endpoint_security_group" "test" { value = "test_value" }, ] - vrf_name = "vrf_name_1" + vrf_name = aci_vrf.test_vrf_0.name } tags = [ { @@ -905,7 +946,7 @@ resource "aci_endpoint_security_group" "test" { value = "test_value" }, ] - contract_name = "contract_name_1" + contract_name = aci_contract.test_contract_1.name priority = "level2" }, ] @@ -942,7 +983,7 @@ resource "aci_endpoint_security_group" "test" { value = "test_value" }, ] - imported_contract_name = "imported_contract_name_1" + imported_contract_name = aci_imported_contract.test_imported_contract_1.name priority = "level2" }, ] @@ -961,7 +1002,7 @@ resource "aci_endpoint_security_group" "test" { value = "test_value" }, ] - contract_name = "contract_name_1" + contract_name = aci_contract.test_contract_1.name }, ] relation_to_provided_contracts = [ @@ -979,7 +1020,7 @@ resource "aci_endpoint_security_group" "test" { value = "test_value" }, ] - contract_name = "contract_name_1" + contract_name = aci_contract.test_contract_1.name match_criteria = "AtleastOne" priority = "level2" }, @@ -998,7 +1039,7 @@ resource "aci_endpoint_security_group" "test" { value = "test_value" }, ] - vrf_name = "vrf_name_1" + vrf_name = aci_vrf.test_vrf_0.name } tags = [ { @@ -1023,8 +1064,34 @@ resource "aci_endpoint_security_group" "test" { annotation = "annotation_1" annotations = [] tags = [] - vrf_name = "vrf_name_1" + vrf_name = aci_vrf.test_vrf_0.name } tags = [] } ` + +const testConfigFvESgLegacyAttributesWithFvAp = testChildDependencyConfigFvESg + testConfigFvApMinDependencyWithFvTenant + ` +resource "aci_endpoint_security_group" "test" { + name = "test_name" + application_profile_dn = aci_application_profile.test.id + match_t = "All" + pc_enf_pref = "enforced" + pref_gr_memb = "exclude" + relation_fv_rs_intra_epg = [aci_contract.test_contract_1.id] + relation_fv_rs_scope = aci_vrf.test_vrf_0.id + relation_fv_rs_sec_inherited = [aci_endpoint_security_group.test_endpoint_security_group_0.id] + relation_fv_rs_cons { + prio = "level1" + target_dn = aci_contract.test_contract_0.id + } + relation_fv_rs_cons_if { + prio = "level1" + target_dn = aci_imported_contract.test_imported_contract_0.id + } + relation_fv_rs_prov { + match_t = "All" + prio = "level1" + target_dn = aci_contract.test_contract_0.id + } +} +` diff --git a/internal/provider/resource_aci_external_management_network_instance_profile.go b/internal/provider/resource_aci_external_management_network_instance_profile.go index 458166b1e..d3482c509 100644 --- a/internal/provider/resource_aci_external_management_network_instance_profile.go +++ b/internal/provider/resource_aci_external_management_network_instance_profile.go @@ -127,6 +127,39 @@ var MgmtRsOoBConsMgmtInstPType = types.ObjectType{ }, } +func MgmtRsOoBConsMgmtInstPSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []MgmtRsOoBConsMgmtInstPResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.Prio.IsNull() { + nullInStateFound = true + planSetValues[index].Prio = customTypes.NewMgmtRsOoBConsPrioStringNull() + } + if stateValue.TnVzOOBBrCPName.IsNull() { + nullInStateFound = true + planSetValues[index].TnVzOOBBrCPName = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, MgmtRsOoBConsMgmtInstPType, planSetValues) + return planSet + +} + // TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel describes the resource data model for the children without relation ships. type TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel struct { Key types.String `tfsdk:"key"` @@ -315,6 +348,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(MgmtRsOoBConsMgmtInstPSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ diff --git a/internal/provider/resource_aci_igmp_snooping_policy.go b/internal/provider/resource_aci_igmp_snooping_policy.go index 8018726c1..54ffa42a7 100644 --- a/internal/provider/resource_aci_igmp_snooping_policy.go +++ b/internal/provider/resource_aci_igmp_snooping_policy.go @@ -222,7 +222,7 @@ func (r *IgmpSnoopPolResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(nil), }, Validators: []validator.Set{ setvalidator.SizeAtMost(4), diff --git a/internal/provider/resource_aci_l3out_consumer_label.go b/internal/provider/resource_aci_l3out_consumer_label.go index 1a27f1738..70d3a984d 100644 --- a/internal/provider/resource_aci_l3out_consumer_label.go +++ b/internal/provider/resource_aci_l3out_consumer_label.go @@ -138,6 +138,35 @@ var L3extRsLblToInstPL3extConsLblType = types.ObjectType{ }, } +func L3extRsLblToInstPL3extConsLblSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []L3extRsLblToInstPL3extConsLblResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.TDn.IsNull() { + nullInStateFound = true + planSetValues[index].TDn = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, L3extRsLblToInstPL3extConsLblType, planSetValues) + return planSet + +} + // TagAnnotationL3extRsLblToInstPL3extConsLblResourceModel describes the resource data model for the children without relation ships. type TagAnnotationL3extRsLblToInstPL3extConsLblResourceModel struct { Key types.String `tfsdk:"key"` @@ -217,6 +246,39 @@ var L3extRsLblToProfileL3extConsLblType = types.ObjectType{ }, } +func L3extRsLblToProfileL3extConsLblSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []L3extRsLblToProfileL3extConsLblResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.Direction.IsNull() { + nullInStateFound = true + planSetValues[index].Direction = basetypes.NewStringNull() + } + if stateValue.TDn.IsNull() { + nullInStateFound = true + planSetValues[index].TDn = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, L3extRsLblToProfileL3extConsLblType, planSetValues) + return planSet + +} + // TagAnnotationL3extRsLblToProfileL3extConsLblResourceModel describes the resource data model for the children without relation ships. type TagAnnotationL3extRsLblToProfileL3extConsLblResourceModel struct { Key types.String `tfsdk:"key"` @@ -439,6 +501,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(L3extRsLblToInstPL3extConsLblSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -518,6 +581,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(L3extRsLblToProfileL3extConsLblSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ diff --git a/internal/provider/resource_aci_mld_snooping_policy.go b/internal/provider/resource_aci_mld_snooping_policy.go index 4f78f55af..f28bc601f 100644 --- a/internal/provider/resource_aci_mld_snooping_policy.go +++ b/internal/provider/resource_aci_mld_snooping_policy.go @@ -222,7 +222,7 @@ func (r *MldSnoopPolResource) Schema(ctx context.Context, req resource.SchemaReq Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(nil), }, Validators: []validator.Set{ setvalidator.SizeAtMost(4), diff --git a/internal/provider/resource_aci_neighbor_discovery_interface_policy.go b/internal/provider/resource_aci_neighbor_discovery_interface_policy.go index acc585d11..e2f142662 100644 --- a/internal/provider/resource_aci_neighbor_discovery_interface_policy.go +++ b/internal/provider/resource_aci_neighbor_discovery_interface_policy.go @@ -218,7 +218,7 @@ func (r *NdIfPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(nil), }, Validators: []validator.Set{ setvalidator.SizeAtMost(6), diff --git a/internal/provider/resource_aci_netflow_exporter_policy_test.go b/internal/provider/resource_aci_netflow_exporter_policy_test.go index 76b273ad8..db14fbd6e 100644 --- a/internal/provider/resource_aci_netflow_exporter_policy_test.go +++ b/internal/provider/resource_aci_netflow_exporter_policy_test.go @@ -546,7 +546,7 @@ resource "aci_netflow_exporter_policy" "test" { } ` -const testConfigNetflowExporterPolCustomTypeDependencyWithFvTenant = testConfigFvTenantMin + ` +const testConfigNetflowExporterPolCustomTypeDependencyWithFvTenant = testChildDependencyConfigNetflowExporterPol + testConfigFvTenantMin + ` resource "aci_netflow_exporter_policy" "test" { parent_dn = aci_tenant.test.id destination_ip_address = "2.2.2.1" diff --git a/internal/provider/resource_aci_netflow_monitor_policy.go b/internal/provider/resource_aci_netflow_monitor_policy.go index 46b3375ad..76ffa0339 100644 --- a/internal/provider/resource_aci_netflow_monitor_policy.go +++ b/internal/provider/resource_aci_netflow_monitor_policy.go @@ -130,6 +130,35 @@ var NetflowRsMonitorToExporterNetflowMonitorPolType = types.ObjectType{ }, } +func NetflowRsMonitorToExporterNetflowMonitorPolSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []NetflowRsMonitorToExporterNetflowMonitorPolResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.TnNetflowExporterPolName.IsNull() { + nullInStateFound = true + planSetValues[index].TnNetflowExporterPolName = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, NetflowRsMonitorToExporterNetflowMonitorPolType, planSetValues) + return planSet + +} + // TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolResourceModel describes the resource data model for the children without relation ships. type TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolResourceModel struct { Key types.String `tfsdk:"key"` @@ -588,6 +617,7 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(NetflowRsMonitorToExporterNetflowMonitorPolSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ diff --git a/internal/provider/resource_aci_netflow_record_policy.go b/internal/provider/resource_aci_netflow_record_policy.go index dee1fe244..1fea77471 100644 --- a/internal/provider/resource_aci_netflow_record_policy.go +++ b/internal/provider/resource_aci_netflow_record_policy.go @@ -200,7 +200,7 @@ func (r *NetflowRecordPolResource) Schema(ctx context.Context, req resource.Sche Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(nil), }, Validators: []validator.Set{ setvalidator.SizeAtMost(8), @@ -225,7 +225,7 @@ func (r *NetflowRecordPolResource) Schema(ctx context.Context, req resource.Sche Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(nil), }, Validators: []validator.Set{ setvalidator.SizeAtMost(14), diff --git a/internal/provider/resource_aci_relation_from_bridge_domain_to_netflow_monitor_policy_test.go b/internal/provider/resource_aci_relation_from_bridge_domain_to_netflow_monitor_policy_test.go index eaae97a19..161bd6df4 100644 --- a/internal/provider/resource_aci_relation_from_bridge_domain_to_netflow_monitor_policy_test.go +++ b/internal/provider/resource_aci_relation_from_bridge_domain_to_netflow_monitor_policy_test.go @@ -189,7 +189,14 @@ func TestAccResourceFvRsBDToNetflowMonitorPolWithFvBD(t *testing.T) { }) } -const testConfigFvRsBDToNetflowMonitorPolMinDependencyWithFvBDAllowExisting = testConfigFvBDMinDependencyWithFvTenant + ` +const testDependencyConfigFvRsBDToNetflowMonitorPol = ` +resource "aci_netflow_monitor_policy" "test_netflow_monitor_policy_0" { + parent_dn = aci_tenant.test.id + name = "netflow_monitor_policy_name_1" +} +` + +const testConfigFvRsBDToNetflowMonitorPolMinDependencyWithFvBDAllowExisting = testDependencyConfigFvRsBDToNetflowMonitorPol + testConfigFvBDMinDependencyWithFvTenant + ` resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "allow_test" { parent_dn = aci_bridge_domain.test.id filter_type = "ipv4" @@ -203,7 +210,7 @@ resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "allow_test } ` -const testConfigFvRsBDToNetflowMonitorPolMinDependencyWithFvBD = testConfigFvBDMinDependencyWithFvTenant + ` +const testConfigFvRsBDToNetflowMonitorPolMinDependencyWithFvBD = testDependencyConfigFvRsBDToNetflowMonitorPol + testConfigFvBDMinDependencyWithFvTenant + ` resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "test" { parent_dn = aci_bridge_domain.test.id filter_type = "ipv4" @@ -211,7 +218,7 @@ resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "test" { } ` -const testConfigFvRsBDToNetflowMonitorPolAllDependencyWithFvBD = testConfigFvBDMinDependencyWithFvTenant + ` +const testConfigFvRsBDToNetflowMonitorPolAllDependencyWithFvBD = testDependencyConfigFvRsBDToNetflowMonitorPol + testConfigFvBDMinDependencyWithFvTenant + ` resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "test" { parent_dn = aci_bridge_domain.test.id netflow_monitor_policy_name = "test_tn_netflow_monitor_pol_name" @@ -220,7 +227,7 @@ resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "test" { } ` -const testConfigFvRsBDToNetflowMonitorPolResetDependencyWithFvBD = testConfigFvBDMinDependencyWithFvTenant + ` +const testConfigFvRsBDToNetflowMonitorPolResetDependencyWithFvBD = testDependencyConfigFvRsBDToNetflowMonitorPol + testConfigFvBDMinDependencyWithFvTenant + ` resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "test" { parent_dn = aci_bridge_domain.test.id netflow_monitor_policy_name = "test_tn_netflow_monitor_pol_name" @@ -228,7 +235,7 @@ resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "test" { filter_type = "ipv4" } ` -const testConfigFvRsBDToNetflowMonitorPolChildrenDependencyWithFvBD = testConfigFvBDMinDependencyWithFvTenant + ` +const testConfigFvRsBDToNetflowMonitorPolChildrenDependencyWithFvBD = testDependencyConfigFvRsBDToNetflowMonitorPol + testConfigFvBDMinDependencyWithFvTenant + ` resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "test" { parent_dn = aci_bridge_domain.test.id filter_type = "ipv4" @@ -256,7 +263,7 @@ resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "test" { } ` -const testConfigFvRsBDToNetflowMonitorPolChildrenRemoveFromConfigDependencyWithFvBD = testConfigFvBDMinDependencyWithFvTenant + ` +const testConfigFvRsBDToNetflowMonitorPolChildrenRemoveFromConfigDependencyWithFvBD = testDependencyConfigFvRsBDToNetflowMonitorPol + testConfigFvBDMinDependencyWithFvTenant + ` resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "test" { parent_dn = aci_bridge_domain.test.id filter_type = "ipv4" @@ -264,7 +271,7 @@ resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "test" { } ` -const testConfigFvRsBDToNetflowMonitorPolChildrenRemoveOneDependencyWithFvBD = testConfigFvBDMinDependencyWithFvTenant + ` +const testConfigFvRsBDToNetflowMonitorPolChildrenRemoveOneDependencyWithFvBD = testDependencyConfigFvRsBDToNetflowMonitorPol + testConfigFvBDMinDependencyWithFvTenant + ` resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "test" { parent_dn = aci_bridge_domain.test.id filter_type = "ipv4" @@ -284,7 +291,7 @@ resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "test" { } ` -const testConfigFvRsBDToNetflowMonitorPolChildrenRemoveAllDependencyWithFvBD = testConfigFvBDMinDependencyWithFvTenant + ` +const testConfigFvRsBDToNetflowMonitorPolChildrenRemoveAllDependencyWithFvBD = testDependencyConfigFvRsBDToNetflowMonitorPol + testConfigFvBDMinDependencyWithFvTenant + ` resource "aci_relation_from_bridge_domain_to_netflow_monitor_policy" "test" { parent_dn = aci_bridge_domain.test.id filter_type = "ipv4" diff --git a/internal/provider/resource_aci_relation_to_consumed_contract_test.go b/internal/provider/resource_aci_relation_to_consumed_contract_test.go index 8bd9dc8dc..dfa00ca5e 100644 --- a/internal/provider/resource_aci_relation_to_consumed_contract_test.go +++ b/internal/provider/resource_aci_relation_to_consumed_contract_test.go @@ -382,7 +382,18 @@ func TestAccResourceFvRsConsWithFvESg(t *testing.T) { }) } -const testConfigFvRsConsMinDependencyWithFvAEPgAllowExisting = testConfigFvAEPgMinDependencyWithFvAp + ` +const testDependencyConfigFvRsCons = ` +resource "aci_contract" "test_contract_0" { + tenant_dn = aci_tenant.test.id + name = "contract_name_0" +} +resource "aci_contract" "test_contract_1" { + tenant_dn = aci_tenant.test.id + name = "contract_name_1" +} +` + +const testConfigFvRsConsMinDependencyWithFvAEPgAllowExisting = testDependencyConfigFvRsCons + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "allow_test" { parent_dn = aci_application_epg.test.id contract_name = "test_tn_vz_br_cp_name" @@ -394,14 +405,14 @@ resource "aci_relation_to_consumed_contract" "allow_test_2" { } ` -const testConfigFvRsConsMinDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsMinDependencyWithFvAEPg = testDependencyConfigFvRsCons + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_application_epg.test.id contract_name = "test_tn_vz_br_cp_name" } ` -const testConfigFvRsConsAllDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsAllDependencyWithFvAEPg = testDependencyConfigFvRsCons + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_application_epg.test.id contract_name = "test_tn_vz_br_cp_name" @@ -410,7 +421,7 @@ resource "aci_relation_to_consumed_contract" "test" { } ` -const testConfigFvRsConsResetDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsResetDependencyWithFvAEPg = testDependencyConfigFvRsCons + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_application_epg.test.id contract_name = "test_tn_vz_br_cp_name" @@ -418,7 +429,7 @@ resource "aci_relation_to_consumed_contract" "test" { priority = "unspecified" } ` -const testConfigFvRsConsChildrenDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsChildrenDependencyWithFvAEPg = testDependencyConfigFvRsCons + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_application_epg.test.id contract_name = "test_tn_vz_br_cp_name" @@ -445,14 +456,14 @@ resource "aci_relation_to_consumed_contract" "test" { } ` -const testConfigFvRsConsChildrenRemoveFromConfigDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsChildrenRemoveFromConfigDependencyWithFvAEPg = testDependencyConfigFvRsCons + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_application_epg.test.id contract_name = "test_tn_vz_br_cp_name" } ` -const testConfigFvRsConsChildrenRemoveOneDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsChildrenRemoveOneDependencyWithFvAEPg = testDependencyConfigFvRsCons + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_application_epg.test.id contract_name = "test_tn_vz_br_cp_name" @@ -471,7 +482,7 @@ resource "aci_relation_to_consumed_contract" "test" { } ` -const testConfigFvRsConsChildrenRemoveAllDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsChildrenRemoveAllDependencyWithFvAEPg = testDependencyConfigFvRsCons + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_application_epg.test.id contract_name = "test_tn_vz_br_cp_name" @@ -480,7 +491,7 @@ resource "aci_relation_to_consumed_contract" "test" { } ` -const testConfigFvRsConsCustomTypeDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsCustomTypeDependencyWithFvAEPg = testDependencyConfigFvRsCons + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_application_epg.test.id contract_name = "test_tn_vz_br_cp_name" @@ -488,7 +499,7 @@ resource "aci_relation_to_consumed_contract" "test" { } ` -const testConfigFvRsConsMinDependencyWithFvESgAllowExisting = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsMinDependencyWithFvESgAllowExisting = testDependencyConfigFvRsCons + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "allow_test" { parent_dn = aci_endpoint_security_group.test.id contract_name = "test_tn_vz_br_cp_name" @@ -500,14 +511,14 @@ resource "aci_relation_to_consumed_contract" "allow_test_2" { } ` -const testConfigFvRsConsMinDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsMinDependencyWithFvESg = testDependencyConfigFvRsCons + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_endpoint_security_group.test.id contract_name = "test_tn_vz_br_cp_name" } ` -const testConfigFvRsConsAllDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsAllDependencyWithFvESg = testDependencyConfigFvRsCons + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_endpoint_security_group.test.id contract_name = "test_tn_vz_br_cp_name" @@ -516,7 +527,7 @@ resource "aci_relation_to_consumed_contract" "test" { } ` -const testConfigFvRsConsResetDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsResetDependencyWithFvESg = testDependencyConfigFvRsCons + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_endpoint_security_group.test.id contract_name = "test_tn_vz_br_cp_name" @@ -524,7 +535,7 @@ resource "aci_relation_to_consumed_contract" "test" { priority = "unspecified" } ` -const testConfigFvRsConsChildrenDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsChildrenDependencyWithFvESg = testDependencyConfigFvRsCons + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_endpoint_security_group.test.id contract_name = "test_tn_vz_br_cp_name" @@ -551,14 +562,14 @@ resource "aci_relation_to_consumed_contract" "test" { } ` -const testConfigFvRsConsChildrenRemoveFromConfigDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsChildrenRemoveFromConfigDependencyWithFvESg = testDependencyConfigFvRsCons + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_endpoint_security_group.test.id contract_name = "test_tn_vz_br_cp_name" } ` -const testConfigFvRsConsChildrenRemoveOneDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsChildrenRemoveOneDependencyWithFvESg = testDependencyConfigFvRsCons + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_endpoint_security_group.test.id contract_name = "test_tn_vz_br_cp_name" @@ -577,7 +588,7 @@ resource "aci_relation_to_consumed_contract" "test" { } ` -const testConfigFvRsConsChildrenRemoveAllDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsChildrenRemoveAllDependencyWithFvESg = testDependencyConfigFvRsCons + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_endpoint_security_group.test.id contract_name = "test_tn_vz_br_cp_name" @@ -586,7 +597,7 @@ resource "aci_relation_to_consumed_contract" "test" { } ` -const testConfigFvRsConsCustomTypeDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsCustomTypeDependencyWithFvESg = testDependencyConfigFvRsCons + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_consumed_contract" "test" { parent_dn = aci_endpoint_security_group.test.id contract_name = "test_tn_vz_br_cp_name" diff --git a/internal/provider/resource_aci_relation_to_contract_master_test.go b/internal/provider/resource_aci_relation_to_contract_master_test.go index e84cac7e0..cf8cfe6ed 100644 --- a/internal/provider/resource_aci_relation_to_contract_master_test.go +++ b/internal/provider/resource_aci_relation_to_contract_master_test.go @@ -22,8 +22,8 @@ func TestAccResourceFvRsSecInheritedWithFvAEPg(t *testing.T) { Config: testConfigFvRsSecInheritedMinDependencyWithFvAEPgAllowExisting, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_contract_master.allow_test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_2"), - resource.TestCheckResourceAttr("aci_relation_to_contract_master.allow_test_2", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_2"), + resource.TestCheckResourceAttr("aci_relation_to_contract_master.allow_test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_0"), + resource.TestCheckResourceAttr("aci_relation_to_contract_master.allow_test_2", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_0"), resource.TestCheckResourceAttr("aci_relation_to_contract_master.allow_test", "annotation", "orchestrator:terraform"), resource.TestCheckResourceAttr("aci_relation_to_contract_master.allow_test_2", "annotation", "orchestrator:terraform"), ), @@ -54,8 +54,8 @@ func TestAccResourceFvRsSecInheritedWithFvAEPg(t *testing.T) { Config: testConfigFvRsSecInheritedMinDependencyWithFvAEPgAllowExisting, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_contract_master.allow_test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_2"), - resource.TestCheckResourceAttr("aci_relation_to_contract_master.allow_test_2", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_2"), + resource.TestCheckResourceAttr("aci_relation_to_contract_master.allow_test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_0"), + resource.TestCheckResourceAttr("aci_relation_to_contract_master.allow_test_2", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_0"), resource.TestCheckResourceAttr("aci_relation_to_contract_master.allow_test", "annotation", "orchestrator:terraform"), resource.TestCheckResourceAttr("aci_relation_to_contract_master.allow_test_2", "annotation", "orchestrator:terraform"), ), @@ -72,7 +72,7 @@ func TestAccResourceFvRsSecInheritedWithFvAEPg(t *testing.T) { Config: testConfigFvRsSecInheritedMinDependencyWithFvAEPg, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_2"), + resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_0"), resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "annotation", "orchestrator:terraform"), ), }, @@ -81,7 +81,7 @@ func TestAccResourceFvRsSecInheritedWithFvAEPg(t *testing.T) { Config: testConfigFvRsSecInheritedAllDependencyWithFvAEPg, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_2"), + resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_0"), resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "annotation", "annotation"), ), }, @@ -90,7 +90,7 @@ func TestAccResourceFvRsSecInheritedWithFvAEPg(t *testing.T) { Config: testConfigFvRsSecInheritedMinDependencyWithFvAEPg, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_2"), + resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_0"), ), }, // Update with empty strings config or default value @@ -98,7 +98,7 @@ func TestAccResourceFvRsSecInheritedWithFvAEPg(t *testing.T) { Config: testConfigFvRsSecInheritedResetDependencyWithFvAEPg, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_2"), + resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_0"), resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "annotation", "orchestrator:terraform"), ), }, @@ -113,7 +113,7 @@ func TestAccResourceFvRsSecInheritedWithFvAEPg(t *testing.T) { Config: testConfigFvRsSecInheritedChildrenDependencyWithFvAEPg, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_2"), + resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "target_dn", "uni/tn-test_tenant/ap-test_ap/epg-epg_0"), resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "annotation", "orchestrator:terraform"), resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "annotations.0.key", "key_0"), resource.TestCheckResourceAttr("aci_relation_to_contract_master.test", "annotations.0.value", "value_1"), @@ -359,11 +359,11 @@ resource "aci_endpoint_security_group" "test_endpoint_security_group_1" { } resource "aci_application_epg" "test_application_epg_0" { application_profile_dn = aci_application_profile.test.id - name = "epg_2" + name = "epg_0" } resource "aci_application_epg" "test_application_epg_1" { application_profile_dn = aci_application_profile.test.id - name = "epg_3" + name = "epg_1" } ` diff --git a/internal/provider/resource_aci_relation_to_imported_contract_test.go b/internal/provider/resource_aci_relation_to_imported_contract_test.go index c3d6cf21d..4b5704188 100644 --- a/internal/provider/resource_aci_relation_to_imported_contract_test.go +++ b/internal/provider/resource_aci_relation_to_imported_contract_test.go @@ -382,7 +382,18 @@ func TestAccResourceFvRsConsIfWithFvESg(t *testing.T) { }) } -const testConfigFvRsConsIfMinDependencyWithFvAEPgAllowExisting = testConfigFvAEPgMinDependencyWithFvAp + ` +const testDependencyConfigFvRsConsIf = ` +resource "aci_imported_contract" "test_imported_contract_0" { + tenant_dn = aci_tenant.test.id + name = "imported_contract_name_0" +} +resource "aci_imported_contract" "test_imported_contract_1" { + tenant_dn = aci_tenant.test.id + name = "imported_contract_name_1" +} +` + +const testConfigFvRsConsIfMinDependencyWithFvAEPgAllowExisting = testDependencyConfigFvRsConsIf + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "allow_test" { parent_dn = aci_application_epg.test.id imported_contract_name = "test_tn_vz_cp_if_name" @@ -394,14 +405,14 @@ resource "aci_relation_to_imported_contract" "allow_test_2" { } ` -const testConfigFvRsConsIfMinDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfMinDependencyWithFvAEPg = testDependencyConfigFvRsConsIf + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_application_epg.test.id imported_contract_name = "test_tn_vz_cp_if_name" } ` -const testConfigFvRsConsIfAllDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfAllDependencyWithFvAEPg = testDependencyConfigFvRsConsIf + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_application_epg.test.id imported_contract_name = "test_tn_vz_cp_if_name" @@ -410,7 +421,7 @@ resource "aci_relation_to_imported_contract" "test" { } ` -const testConfigFvRsConsIfResetDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfResetDependencyWithFvAEPg = testDependencyConfigFvRsConsIf + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_application_epg.test.id imported_contract_name = "test_tn_vz_cp_if_name" @@ -418,7 +429,7 @@ resource "aci_relation_to_imported_contract" "test" { priority = "unspecified" } ` -const testConfigFvRsConsIfChildrenDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfChildrenDependencyWithFvAEPg = testDependencyConfigFvRsConsIf + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_application_epg.test.id imported_contract_name = "test_tn_vz_cp_if_name" @@ -445,14 +456,14 @@ resource "aci_relation_to_imported_contract" "test" { } ` -const testConfigFvRsConsIfChildrenRemoveFromConfigDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfChildrenRemoveFromConfigDependencyWithFvAEPg = testDependencyConfigFvRsConsIf + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_application_epg.test.id imported_contract_name = "test_tn_vz_cp_if_name" } ` -const testConfigFvRsConsIfChildrenRemoveOneDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfChildrenRemoveOneDependencyWithFvAEPg = testDependencyConfigFvRsConsIf + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_application_epg.test.id imported_contract_name = "test_tn_vz_cp_if_name" @@ -471,7 +482,7 @@ resource "aci_relation_to_imported_contract" "test" { } ` -const testConfigFvRsConsIfChildrenRemoveAllDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfChildrenRemoveAllDependencyWithFvAEPg = testDependencyConfigFvRsConsIf + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_application_epg.test.id imported_contract_name = "test_tn_vz_cp_if_name" @@ -480,7 +491,7 @@ resource "aci_relation_to_imported_contract" "test" { } ` -const testConfigFvRsConsIfCustomTypeDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfCustomTypeDependencyWithFvAEPg = testDependencyConfigFvRsConsIf + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_application_epg.test.id imported_contract_name = "test_tn_vz_cp_if_name" @@ -488,7 +499,7 @@ resource "aci_relation_to_imported_contract" "test" { } ` -const testConfigFvRsConsIfMinDependencyWithFvESgAllowExisting = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfMinDependencyWithFvESgAllowExisting = testDependencyConfigFvRsConsIf + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "allow_test" { parent_dn = aci_endpoint_security_group.test.id imported_contract_name = "test_tn_vz_cp_if_name" @@ -500,14 +511,14 @@ resource "aci_relation_to_imported_contract" "allow_test_2" { } ` -const testConfigFvRsConsIfMinDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfMinDependencyWithFvESg = testDependencyConfigFvRsConsIf + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_endpoint_security_group.test.id imported_contract_name = "test_tn_vz_cp_if_name" } ` -const testConfigFvRsConsIfAllDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfAllDependencyWithFvESg = testDependencyConfigFvRsConsIf + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_endpoint_security_group.test.id imported_contract_name = "test_tn_vz_cp_if_name" @@ -516,7 +527,7 @@ resource "aci_relation_to_imported_contract" "test" { } ` -const testConfigFvRsConsIfResetDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfResetDependencyWithFvESg = testDependencyConfigFvRsConsIf + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_endpoint_security_group.test.id imported_contract_name = "test_tn_vz_cp_if_name" @@ -524,7 +535,7 @@ resource "aci_relation_to_imported_contract" "test" { priority = "unspecified" } ` -const testConfigFvRsConsIfChildrenDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfChildrenDependencyWithFvESg = testDependencyConfigFvRsConsIf + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_endpoint_security_group.test.id imported_contract_name = "test_tn_vz_cp_if_name" @@ -551,14 +562,14 @@ resource "aci_relation_to_imported_contract" "test" { } ` -const testConfigFvRsConsIfChildrenRemoveFromConfigDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfChildrenRemoveFromConfigDependencyWithFvESg = testDependencyConfigFvRsConsIf + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_endpoint_security_group.test.id imported_contract_name = "test_tn_vz_cp_if_name" } ` -const testConfigFvRsConsIfChildrenRemoveOneDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfChildrenRemoveOneDependencyWithFvESg = testDependencyConfigFvRsConsIf + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_endpoint_security_group.test.id imported_contract_name = "test_tn_vz_cp_if_name" @@ -577,7 +588,7 @@ resource "aci_relation_to_imported_contract" "test" { } ` -const testConfigFvRsConsIfChildrenRemoveAllDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfChildrenRemoveAllDependencyWithFvESg = testDependencyConfigFvRsConsIf + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_endpoint_security_group.test.id imported_contract_name = "test_tn_vz_cp_if_name" @@ -586,7 +597,7 @@ resource "aci_relation_to_imported_contract" "test" { } ` -const testConfigFvRsConsIfCustomTypeDependencyWithFvESg = testConfigFvESgMinDependencyWithFvAp + ` +const testConfigFvRsConsIfCustomTypeDependencyWithFvESg = testDependencyConfigFvRsConsIf + testConfigFvESgMinDependencyWithFvAp + ` resource "aci_relation_to_imported_contract" "test" { parent_dn = aci_endpoint_security_group.test.id imported_contract_name = "test_tn_vz_cp_if_name" diff --git a/internal/provider/resource_aci_relation_to_taboo_contract_test.go b/internal/provider/resource_aci_relation_to_taboo_contract_test.go index af29e6f97..3a228cd74 100644 --- a/internal/provider/resource_aci_relation_to_taboo_contract_test.go +++ b/internal/provider/resource_aci_relation_to_taboo_contract_test.go @@ -180,7 +180,18 @@ func TestAccResourceFvRsProtByWithFvAEPg(t *testing.T) { }) } -const testConfigFvRsProtByMinDependencyWithFvAEPgAllowExisting = testConfigFvAEPgMinDependencyWithFvAp + ` +const testDependencyConfigFvRsProtBy = ` +resource "aci_taboo_contract" "test_taboo_contract_0" { + tenant_dn = aci_tenant.test.id + name = "taboo_contract_name_0" +} +resource "aci_taboo_contract" "test_taboo_contract_1" { + tenant_dn = aci_tenant.test.id + name = "taboo_contract_name_1" +} +` + +const testConfigFvRsProtByMinDependencyWithFvAEPgAllowExisting = testDependencyConfigFvRsProtBy + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_taboo_contract" "allow_test" { parent_dn = aci_application_epg.test.id taboo_contract_name = "test_tn_vz_taboo_name" @@ -192,14 +203,14 @@ resource "aci_relation_to_taboo_contract" "allow_test_2" { } ` -const testConfigFvRsProtByMinDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsProtByMinDependencyWithFvAEPg = testDependencyConfigFvRsProtBy + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_taboo_contract" "test" { parent_dn = aci_application_epg.test.id taboo_contract_name = "test_tn_vz_taboo_name" } ` -const testConfigFvRsProtByAllDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsProtByAllDependencyWithFvAEPg = testDependencyConfigFvRsProtBy + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_taboo_contract" "test" { parent_dn = aci_application_epg.test.id taboo_contract_name = "test_tn_vz_taboo_name" @@ -207,14 +218,14 @@ resource "aci_relation_to_taboo_contract" "test" { } ` -const testConfigFvRsProtByResetDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsProtByResetDependencyWithFvAEPg = testDependencyConfigFvRsProtBy + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_taboo_contract" "test" { parent_dn = aci_application_epg.test.id taboo_contract_name = "test_tn_vz_taboo_name" annotation = "orchestrator:terraform" } ` -const testConfigFvRsProtByChildrenDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsProtByChildrenDependencyWithFvAEPg = testDependencyConfigFvRsProtBy + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_taboo_contract" "test" { parent_dn = aci_application_epg.test.id taboo_contract_name = "test_tn_vz_taboo_name" @@ -241,14 +252,14 @@ resource "aci_relation_to_taboo_contract" "test" { } ` -const testConfigFvRsProtByChildrenRemoveFromConfigDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsProtByChildrenRemoveFromConfigDependencyWithFvAEPg = testDependencyConfigFvRsProtBy + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_taboo_contract" "test" { parent_dn = aci_application_epg.test.id taboo_contract_name = "test_tn_vz_taboo_name" } ` -const testConfigFvRsProtByChildrenRemoveOneDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsProtByChildrenRemoveOneDependencyWithFvAEPg = testDependencyConfigFvRsProtBy + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_taboo_contract" "test" { parent_dn = aci_application_epg.test.id taboo_contract_name = "test_tn_vz_taboo_name" @@ -267,7 +278,7 @@ resource "aci_relation_to_taboo_contract" "test" { } ` -const testConfigFvRsProtByChildrenRemoveAllDependencyWithFvAEPg = testConfigFvAEPgMinDependencyWithFvAp + ` +const testConfigFvRsProtByChildrenRemoveAllDependencyWithFvAEPg = testDependencyConfigFvRsProtBy + testConfigFvAEPgMinDependencyWithFvAp + ` resource "aci_relation_to_taboo_contract" "test" { parent_dn = aci_application_epg.test.id taboo_contract_name = "test_tn_vz_taboo_name" diff --git a/internal/provider/resource_aci_vrf_fallback_route_group.go b/internal/provider/resource_aci_vrf_fallback_route_group.go index 720c0843d..973b905ba 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group.go @@ -142,6 +142,47 @@ var FvFBRMemberFvFBRGroupType = types.ObjectType{ }, } +func FvFBRMemberFvFBRGroupSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(ctx context.Context, planValue, stateValue types.Set) basetypes.SetValue { + // Function is needed to handle the case that an attribute is not yet suppored in a version and gets set to null during read + var planSetValues, stateSetValues []FvFBRMemberFvFBRGroupResourceModel + stateValue.ElementsAs(ctx, &stateSetValues, false) + planValue.ElementsAs(ctx, &planSetValues, false) + + // If the length of the state and plan values are different a change is already detected the loop can be skipped + if len(stateSetValues) == len(planSetValues) { + for index, stateValue := range stateSetValues { + nullInStateFound := false + if stateValue.Annotation.IsNull() { + nullInStateFound = true + planSetValues[index].Annotation = basetypes.NewStringNull() + } + if stateValue.Descr.IsNull() { + nullInStateFound = true + planSetValues[index].Descr = basetypes.NewStringNull() + } + if stateValue.Name.IsNull() { + nullInStateFound = true + planSetValues[index].Name = basetypes.NewStringNull() + } + if stateValue.NameAlias.IsNull() { + nullInStateFound = true + planSetValues[index].NameAlias = basetypes.NewStringNull() + } + if stateValue.RnhAddr.IsNull() { + nullInStateFound = true + planSetValues[index].RnhAddr = basetypes.NewStringNull() + } + if !nullInStateFound { + // when there are no null fields we can conclude the version supports all attributes in set + break + } + } + } + planSet, _ := types.SetValueFrom(ctx, FvFBRMemberFvFBRGroupType, planSetValues) + return planSet + +} + // TagAnnotationFvFBRMemberFvFBRGroupResourceModel describes the resource data model for the children without relation ships. type TagAnnotationFvFBRMemberFvFBRGroupResourceModel struct { Key types.String `tfsdk:"key"` @@ -412,6 +453,7 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(FvFBRMemberFvFBRGroupSetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ diff --git a/internal/provider/utils.go b/internal/provider/utils.go index ea7a11655..b49803748 100644 --- a/internal/provider/utils.go +++ b/internal/provider/utils.go @@ -170,10 +170,14 @@ func (m setToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate) PlanModifyStrin } } -type setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate struct{} +type setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate struct { + resourceFunction func(ctx context.Context, planValue types.Set, stateValue types.Set) types.Set +} -func SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate() planmodifier.Set { - return setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate{} +func SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(resourceFunction func(ctx context.Context, planValue types.Set, stateValue types.Set) types.Set) planmodifier.Set { + return setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate{ + resourceFunction: resourceFunction, + } } func (m setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate) Description(_ context.Context) string { @@ -189,6 +193,8 @@ func (m setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate) PlanModifySet(ctx // Set the plan value to SetType null when state value is null and plan value is unknown during an Update if !req.State.Raw.IsNull() && req.StateValue.IsNull() && req.PlanValue.IsUnknown() { resp.PlanValue = types.SetNull(req.StateValue.ElementType(ctx)) + } else if !req.State.Raw.IsNull() && !req.StateValue.IsNull() && !req.PlanValue.IsUnknown() && m.resourceFunction != nil { + resp.PlanValue = m.resourceFunction(ctx, req.PlanValue, req.StateValue) } }