From a48b2e031386c49a590fe3706f27ed03fee137eb Mon Sep 17 00:00:00 2001 From: Shreyas Date: Fri, 22 Mar 2024 11:05:54 -0400 Subject: [PATCH 01/20] [minor_change] Addition of recursive logic in the templates to incorporate grand children of the parent class as nested children within the immediate child of the parent --- docs/data-sources/communication_policy.md | 81 + docs/resources/communication_policy.md | 201 ++ .../aci_communication_policy/data-source.tf | 4 + .../aci_communication_policy/provider.tf | 14 + .../aci_communication_policy/provider.tf | 14 + .../resource-all-attributes.tf | 42 + .../aci_communication_policy/resource.tf | 4 + gen/generator.go | 111 +- gen/meta/commHttps.json | 1798 +++++++++++++++++ gen/meta/commPol.json | 800 ++++++++ gen/meta/commRsClientCertCA.json | 912 +++++++++ gen/meta/commRsKeyRing.json | 1010 +++++++++ gen/templates/resource.go.tmpl | 151 +- gen/testvars/commPol.yaml | 84 + .../data_source_aci_communication_policy.go | 247 +++ ...ta_source_aci_communication_policy_test.go | 51 + internal/provider/provider.go | 2 + .../resource_aci_communication_policy.go | 1036 ++++++++++ .../resource_aci_communication_policy_test.go | 411 ++++ 19 files changed, 6864 insertions(+), 109 deletions(-) create mode 100644 docs/data-sources/communication_policy.md create mode 100644 docs/resources/communication_policy.md create mode 100644 examples/data-sources/aci_communication_policy/data-source.tf create mode 100644 examples/data-sources/aci_communication_policy/provider.tf create mode 100644 examples/resources/aci_communication_policy/provider.tf create mode 100644 examples/resources/aci_communication_policy/resource-all-attributes.tf create mode 100644 examples/resources/aci_communication_policy/resource.tf create mode 100644 gen/meta/commHttps.json create mode 100644 gen/meta/commPol.json create mode 100644 gen/meta/commRsClientCertCA.json create mode 100644 gen/meta/commRsKeyRing.json create mode 100644 gen/testvars/commPol.yaml create mode 100644 internal/provider/data_source_aci_communication_policy.go create mode 100644 internal/provider/data_source_aci_communication_policy_test.go create mode 100644 internal/provider/resource_aci_communication_policy.go create mode 100644 internal/provider/resource_aci_communication_policy_test.go diff --git a/docs/data-sources/communication_policy.md b/docs/data-sources/communication_policy.md new file mode 100644 index 000000000..6f8647135 --- /dev/null +++ b/docs/data-sources/communication_policy.md @@ -0,0 +1,81 @@ +--- +# Documentation 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). +subcategory: "Generic" +layout: "aci" +page_title: "ACI: aci_communication_policy" +sidebar_current: "docs-aci-data-source-aci_communication_policy" +description: |- + Data source for Communication Policy +--- + +# aci_communication_policy # + +Data source for Communication Policy + +## API Information ## + +* Class: [commPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commPol/overview) + +* Supported in ACI versions: 1.0(1e) and later. + +* Distinguished Name Format: `uni/fabric/comm-{name}` + +## GUI Information ## + +* Location: `Generic` + +## Example Usage ## + +```hcl + +data "aci_communication_policy" "example" { + name = "test_name" +} + +``` + +## Schema ## + +### Required ### + +* `name` (name) - (string) The name of the Communication Policy object. + +### Read-Only ### + +* `id` - (string) The distinguished name (DN) of the Communication Policy object. +* `annotation` (annotation) - (string) The annotation of the Communication Policy object. +* `description` (descr) - (string) The description of the Communication Policy object. +* `name_alias` (nameAlias) - (string) The name alias of the Communication Policy object. +* `owner_key` (ownerKey) - (string) The key for enabling clients to own their data for entity correlation. +* `owner_tag` (ownerTag) - (string) A tag for enabling clients to add their own data. For example, to indicate who created this object. +* `strict_security_on_apic_oob_subnet` (strictSecurityOnApicOOBSubnet) - (string) remove implicit access on apic oob from any apic OOB subnet IP. + +* `http_ssl_configuration` - (list) A list of Http Ssl Configuration objects ([commHttps](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commHttps/overview)). + * `access_control_allow_credential` (accessControlAllowCredential) - (string) accessControlAllowCredential. + * `access_control_allow_origins` (accessControlAllowOrigins) - (string) + * `admin_st` (adminSt) - (string) The state of HTTPS communication service. This can be enabled or disabled. + * `annotation` (annotation) - (string) The annotation of the Http Ssl Configuration object. + * `cli_only_mode` (cliOnlyMode) - (string) CLI only mode. + * `client_cert_auth_state` (clientCertAuthState) - (string) Client Cert Auth State. + * `description` (descr) - (string) The description of the Http Ssl Configuration object. + * `dh_param` (dhParam) - (string) DH Parameter. + * `global_throttle_rate` (globalThrottleRate) - (string) The maximum MO api calls allowed per unit time. + * `global_throttle_st` (globalThrottleSt) - (string) Throttle state for all clients without tag0 in header. + * `global_throttle_unit` (globalThrottleUnit) - (string) Unit of rate limit. + * `max_request_status_count` (maxRequestStatusCount) - (string) The maximum number of request status objects to keep. + * `name` (name) - (string) The name of the Http Ssl Configuration object. + * `name_alias` (nameAlias) - (string) The name alias of the Http Ssl Configuration object. + * `node_exporter` (nodeExporter) - (string) Node Exporter service. + * `port` (port) - (string) The port used for HTTPS communication service. + * `referer` (referer) - (string) Allowed HTTP referer space separated list. + * `server_header` (serverHeader) - (string) Server Header. + * `ssl_protocols` (sslProtocols) - (list) The Secure Socket Layer (SSL) protocol. + * `throttle_rate` (throttleRate) - (string) The maximum login/refresh allowed per second. + * `throttle_st` (throttleSt) - (string) Login/refresh throttle state. + * `visore_access` (visoreAccess) - (string) Visore Access. + +* `annotations` - (list) A list of Annotations objects ([tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/resources/communication_policy.md b/docs/resources/communication_policy.md new file mode 100644 index 000000000..c9971c1a8 --- /dev/null +++ b/docs/resources/communication_policy.md @@ -0,0 +1,201 @@ +--- +# Documentation 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). +subcategory: "Generic" +layout: "aci" +page_title: "ACI: aci_communication_policy" +sidebar_current: "docs-aci-resource-aci_communication_policy" +description: |- + Manages ACI Communication Policy +--- + +# aci_communication_policy # + +Manages ACI Communication Policy + + + +## API Information ## + +* Class: [commPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commPol/overview) + +* Supported in ACI versions: 1.0(1e) and later. + +* Distinguished Name Format: `uni/fabric/comm-{name}` + +## GUI Information ## + +* Location: `Generic` + +## Example Usage ## + +The configuration snippet below creates a Communication Policy with only required attributes. + +```hcl + +resource "aci_communication_policy" "example" { + name = "test_name" +} + +``` +The configuration snippet below shows all possible attributes of the Communication Policy. + +!> This example might not be valid configuration and is only used to show all possible attributes. + +```hcl + +resource "aci_communication_policy" "full_example" { + annotation = "annotation" + description = "description" + name = "test_name" + name_alias = "name_alias" + owner_key = "owner_key" + owner_tag = "owner_tag" + strict_security_on_apic_oob_subnet = "no" + http_ssl_configuration = [ + { + access_control_allow_credential = "disabled" + access_control_allow_origins = "access_control_allow_origins_1" + admin_st = "disabled" + annotation = "annotation_1" + cli_only_mode = "disabled" + client_cert_auth_state = "disabled" + description = "description_1" + dh_param = "1024" + global_throttle_rate = "global_throttle_rate_1" + global_throttle_st = "disabled" + global_throttle_unit = "global_throttle_unit_1" + max_request_status_count = "max_request_status_count_1" + name = "name_1" + name_alias = "name_alias_1" + node_exporter = "disabled" + port = "port_1" + referer = "referer_1" + server_header = "disabled" + ssl_protocols = "TLSv1" + throttle_rate = "throttle_rate_1" + throttle_st = "disabled" + visore_access = "disabled" + } + ] + annotations = [ + { + key = "annotations_1" + value = "value_1" + } + ] +} + +``` + +All examples for the Communication Policy resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_communication_policy) folder. + +## Schema ## + +### Required ### + +* `name` (name) - (string) The name of the Communication Policy object. + +### Read-Only ### + +* `id` - (string) The distinguished name (DN) of the Communication Policy object. + +### Optional ### + +* `annotation` (annotation) - (string) The annotation of the Communication Policy object. + - Default: `orchestrator:terraform` +* `description` (descr) - (string) The description of the Communication Policy object. +* `name_alias` (nameAlias) - (string) The name alias of the Communication Policy object. +* `owner_key` (ownerKey) - (string) The key for enabling clients to own their data for entity correlation. +* `owner_tag` (ownerTag) - (string) A tag for enabling clients to add their own data. For example, to indicate who created this object. +* `strict_security_on_apic_oob_subnet` (strictSecurityOnApicOOBSubnet) - (string) remove implicit access on apic oob from any apic OOB subnet IP. + - Default: `false` + - Valid Values: `no`, `yes`. + +* `http_ssl_configuration` - (list) A list of Http Ssl Configuration objects ([commHttps](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commHttps/overview)). Http Ssl Configuration can also be configured using a separate [aci_](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/) resource. + + #### Required #### + + + #### Optional #### + + * `access_control_allow_credential` (accessControlAllowCredential) - (string) accessControlAllowCredential. + - Default: `disabled` + - Valid Values: `disabled`, `enabled`. + * `access_control_allow_origins` (accessControlAllowOrigins) - (string) + * `admin_st` (adminSt) - (string) The state of HTTPS communication service. This can be enabled or disabled. + - Default: `enabled` + - Valid Values: `disabled`, `enabled`. + * `annotation` (annotation) - (string) The annotation of the Http Ssl Configuration object. + - Default: `orchestrator:terraform` + * `cli_only_mode` (cliOnlyMode) - (string) CLI only mode. + - Default: `disabled` + - Valid Values: `disabled`, `enabled`. + * `client_cert_auth_state` (clientCertAuthState) - (string) Client Cert Auth State. + - Default: `disabled` + - Valid Values: `disabled`, `enabled`. + * `description` (descr) - (string) The description of the Http Ssl Configuration object. + * `dh_param` (dhParam) - (string) DH Parameter. + - Default: `none` + - Valid Values: `1024`, `2048`, `4096`, `none`. + * `global_throttle_rate` (globalThrottleRate) - (string) The maximum MO api calls allowed per unit time. + - Default: `10000.000000` + * `global_throttle_st` (globalThrottleSt) - (string) Throttle state for all clients without tag0 in header. + - Default: `disabled` + - Valid Values: `disabled`, `enabled`. + * `global_throttle_unit` (globalThrottleUnit) - (string) Unit of rate limit. + - Default: `r/s` + * `max_request_status_count` (maxRequestStatusCount) - (string) The maximum number of request status objects to keep. + * `name` (name) - (string) The name of the Http Ssl Configuration object. + - Default: `https` + * `name_alias` (nameAlias) - (string) The name alias of the Http Ssl Configuration object. + * `node_exporter` (nodeExporter) - (string) Node Exporter service. + - Default: `disabled` + - Valid Values: `disabled`, `enabled`. + * `port` (port) - (string) The port used for HTTPS communication service. + - Default: `443.000000` + * `referer` (referer) - (string) Allowed HTTP referer space separated list. + * `server_header` (serverHeader) - (string) Server Header. + - Default: `enabled` + - Valid Values: `disabled`, `enabled`. + * `ssl_protocols` (sslProtocols) - (list) The Secure Socket Layer (SSL) protocol. + - Default: `TLSv1.1,TLSv1.2` + - Valid Values: `TLSv1`, `TLSv1.1`, `TLSv1.2`, `TLSv1.3`. + * `throttle_rate` (throttleRate) - (string) The maximum login/refresh allowed per second. + - Default: `2.000000` + * `throttle_st` (throttleSt) - (string) Login/refresh throttle state. + - Default: `enabled` + - Valid Values: `disabled`, `enabled`. + * `visore_access` (visoreAccess) - (string) Visore Access. + - Default: `enabled` + - Valid Values: `disabled`, `enabled`. + +* `annotations` - (list) A list of Annotations objects ([tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +## Importing + +An existing Communication Policy can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: + +``` +terraform import aci_communication_policy.example uni/fabric/comm-{name} +``` + +Starting in Terraform version 1.5, an existing Communication Policy can be imported +using [import blocks](https://developer.hashicorp.com/terraform/language/import) via the following configuration: + +``` +import { + id = "uni/fabric/comm-{name}" + to = aci_communication_policy.example +} +``` + +## Child Resources + + - [aci_http_ssl_configuration](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/http_ssl_configuration) \ No newline at end of file diff --git a/examples/data-sources/aci_communication_policy/data-source.tf b/examples/data-sources/aci_communication_policy/data-source.tf new file mode 100644 index 000000000..65b195f27 --- /dev/null +++ b/examples/data-sources/aci_communication_policy/data-source.tf @@ -0,0 +1,4 @@ + +data "aci_communication_policy" "example" { + name = "test_name" +} diff --git a/examples/data-sources/aci_communication_policy/provider.tf b/examples/data-sources/aci_communication_policy/provider.tf new file mode 100644 index 000000000..975fca093 --- /dev/null +++ b/examples/data-sources/aci_communication_policy/provider.tf @@ -0,0 +1,14 @@ +terraform { + required_providers { + aci = { + source = "ciscodevnet/aci" + } + } +} + +provider "aci" { + username = "" + password = "" + url = "" + insecure = true +} \ No newline at end of file diff --git a/examples/resources/aci_communication_policy/provider.tf b/examples/resources/aci_communication_policy/provider.tf new file mode 100644 index 000000000..975fca093 --- /dev/null +++ b/examples/resources/aci_communication_policy/provider.tf @@ -0,0 +1,14 @@ +terraform { + required_providers { + aci = { + source = "ciscodevnet/aci" + } + } +} + +provider "aci" { + username = "" + password = "" + url = "" + insecure = true +} \ No newline at end of file diff --git a/examples/resources/aci_communication_policy/resource-all-attributes.tf b/examples/resources/aci_communication_policy/resource-all-attributes.tf new file mode 100644 index 000000000..9797a184f --- /dev/null +++ b/examples/resources/aci_communication_policy/resource-all-attributes.tf @@ -0,0 +1,42 @@ + +resource "aci_communication_policy" "full_example" { + annotation = "annotation" + description = "description" + name = "test_name" + name_alias = "name_alias" + owner_key = "owner_key" + owner_tag = "owner_tag" + strict_security_on_apic_oob_subnet = "no" + http_ssl_configuration = [ + { + access_control_allow_credential = "disabled" + access_control_allow_origins = "access_control_allow_origins_1" + admin_st = "disabled" + annotation = "annotation_1" + cli_only_mode = "disabled" + client_cert_auth_state = "disabled" + description = "description_1" + dh_param = "1024" + global_throttle_rate = "global_throttle_rate_1" + global_throttle_st = "disabled" + global_throttle_unit = "global_throttle_unit_1" + max_request_status_count = "max_request_status_count_1" + name = "name_1" + name_alias = "name_alias_1" + node_exporter = "disabled" + port = "port_1" + referer = "referer_1" + server_header = "disabled" + ssl_protocols = "TLSv1" + throttle_rate = "throttle_rate_1" + throttle_st = "disabled" + visore_access = "disabled" + } + ] + annotations = [ + { + key = "annotations_1" + value = "value_1" + } + ] +} diff --git a/examples/resources/aci_communication_policy/resource.tf b/examples/resources/aci_communication_policy/resource.tf new file mode 100644 index 000000000..36e5d6cfe --- /dev/null +++ b/examples/resources/aci_communication_policy/resource.tf @@ -0,0 +1,4 @@ + +resource "aci_communication_policy" "example" { + name = "test_name" +} diff --git a/gen/generator.go b/gen/generator.go index ba1228518..de5716d71 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -291,7 +291,7 @@ func getClassModels(definitions Definitions) map[string]Model { for _, pkgName := range pkgNames { classModel := Model{PkgName: pkgName} - classModel.setClassModel(metaPath, false, definitions, []string{}, pkgNames) + classModel.setClassModel(metaPath, false, definitions, []string{}, pkgNames, nil) classModels[pkgName] = classModel } return classModels @@ -556,20 +556,10 @@ func main() { // When done before additional files would need to be opened and read which would slow down the generation process model.ResourceName = GetResourceName(model.PkgName, definitions) model.RelationshipResourceName = GetResourceName(model.RelationshipClass, definitions) - childMap := make(map[string]Model, 0) - for childName, childModel := range model.Children { - childModel.ChildResourceName = GetResourceName(childModel.PkgName, definitions) - if len(childModel.IdentifiedBy) > 0 { - // TODO add logic to determine the naming for plural child resources - childModel.ResourceNameDocReference = childModel.ChildResourceName - childModel.ResourceName = fmt.Sprintf("%ss", childModel.ChildResourceName) - } else { - childModel.ResourceName = childModel.ChildResourceName - } - childModel.RelationshipResourceName = GetResourceName(childModel.RelationshipClass, definitions) - childMap[childName] = childModel - } - model.Children = childMap + model.Children = SetChildClassNames(definitions, model.Children) + // for key, val := range model.Children { + // log.Printf("HERE %v %v", key, val.Children) + // } // Set the documentation specific information for the resource // This is done to ensure references can be made to parent/child resources and output amounts can be restricted @@ -647,6 +637,7 @@ type Model struct { RelationshipClass string RelationshipResourceName string Versions string + ParentName string ChildClasses []string ContainedBy []string Contains []string @@ -722,7 +713,7 @@ type Definitions struct { } // Reads the class details from the meta file and sets all details to the Model -func (m *Model) setClassModel(metaPath string, child bool, definitions Definitions, parents, pkgNames []string) { +func (m *Model) setClassModel(metaPath string, isChildIteration bool, definitions Definitions, parents, pkgNames, mainParentChildren []string) { fileContent, err := os.ReadFile(fmt.Sprintf("%s/%s.json", metaPath, m.PkgName)) if err != nil { log.Fatal("Error when opening file: ", err) @@ -739,7 +730,7 @@ func (m *Model) setClassModel(metaPath string, child bool, definitions Definitio m.Configuration = GetClassConfiguration(m.PkgName, definitions) for _, classDetails := range classInfo { - m.SetClassLabel(classDetails, child) + m.SetClassLabel(classDetails) m.SetClassName(classDetails) m.SetClassRnFormat(classDetails) m.SetClassDnFormats(classDetails) @@ -751,7 +742,10 @@ func (m *Model) setClassModel(metaPath string, child bool, definitions Definitio m.SetClassComment(classDetails) m.SetClassVersions(classDetails) m.SetClassProperties(classDetails) - m.SetClassChildren(classDetails, pkgNames) + m.SetClassChildren(classDetails, pkgNames, mainParentChildren) + if len(parents) != 0 { + m.SetParentName(parents) + } m.SetResourceNotesAndWarnigns(m.PkgName, definitions) m.SetResourceNameAsDescription(m.PkgName, definitions) } @@ -762,38 +756,38 @@ func (m *Model) setClassModel(metaPath string, child bool, definitions Definitio - Incorrect: Parent -> Child -> Grandchild // TODO add grandchild logic */ - if !child { - if len(m.ChildClasses) > 0 { - m.HasChild = true - m.Children = make(map[string]Model) - for _, child := range m.ChildClasses { - childModel := Model{PkgName: child} - childModel.setClassModel(metaPath, true, definitions, []string{m.PkgName}, pkgNames) - m.Children[child] = childModel - if childModel.HasValidValues { - m.HasValidValues = true - } - if len(childModel.IdentifiedBy) == 0 { - m.HasChildWithoutIdentifier = true - } - if childModel.AllowDelete { - m.AllowChildDelete = true - } - if childModel.HasBitmask { - m.HasBitmask = true - } - if childModel.HasNamedProperties { - m.HasNamedProperties = true - m.HasChildNamedProperties = true - } + + if len(m.ChildClasses) > 0 { + mainParentChildren := append(mainParentChildren, m.ChildClasses...) + m.HasChild = true + m.Children = make(map[string]Model) + for _, child := range m.ChildClasses { + childModel := Model{PkgName: child} + childModel.setClassModel(metaPath, true, definitions, []string{m.ResourceClassName}, pkgNames, mainParentChildren) + m.Children[child] = childModel + if childModel.HasValidValues { + m.HasValidValues = true + } + if len(childModel.IdentifiedBy) == 0 { + m.HasChildWithoutIdentifier = true + } + if childModel.AllowDelete { + m.AllowChildDelete = true + } + if childModel.HasBitmask { + m.HasBitmask = true + } + if childModel.HasNamedProperties { + m.HasNamedProperties = true + m.HasChildNamedProperties = true } - } else { - m.HasChild = false } + } else { + m.HasChild = false } } -func (m *Model) SetClassLabel(classDetails interface{}, child bool) { +func (m *Model) SetClassLabel(classDetails interface{}) { m.Label = cleanLabel(classDetails.(map[string]interface{})["label"].(string)) if slices.Contains(labels, m.Label) || m.Label == "" { if !slices.Contains(duplicateLabels, m.Label) { @@ -877,14 +871,14 @@ func (m *Model) SetClassIdentifiers(classDetails interface{}) { m.IdentifiedBy = uniqueInterfaceSlice(classDetails.(map[string]interface{})["identifiedBy"].([]interface{})) } -func (m *Model) SetClassChildren(classDetails interface{}, pkgNames []string) { +func (m *Model) SetClassChildren(classDetails interface{}, pkgNames, mainParentChildren []string) { childClasses := []string{} rnMap := classDetails.(map[string]interface{})["rnMap"].(map[string]interface{}) for rn, className := range rnMap { // TODO check if this condition is correct since there might be cases where that we should exclude if !strings.HasSuffix(rn, "-") || strings.HasPrefix(rn, "rs") || slices.Contains(alwaysIncludeChildren, className.(string)) { pkgName := strings.ReplaceAll(className.(string), ":", "") - if slices.Contains(pkgNames, pkgName) { + if slices.Contains(pkgNames, pkgName) && !slices.Contains(mainParentChildren, pkgName) { childClasses = append(childClasses, pkgName) } } @@ -903,6 +897,25 @@ func (m *Model) SetClassChildren(classDetails interface{}, pkgNames []string) { m.ChildClasses = uniqueStringSlice(childClasses) } +func SetChildClassNames(definitions Definitions, children map[string]Model) map[string]Model { + childMap := make(map[string]Model, 0) + for childName, childModel := range children { + childModel.ChildResourceName = GetResourceName(childModel.PkgName, definitions) + if len(childModel.IdentifiedBy) > 0 { + // TODO add logic to determine the naming for plural child resources + childModel.ResourceNameDocReference = childModel.ChildResourceName + childModel.ResourceName = fmt.Sprintf("%ss", childModel.ChildResourceName) + } else { + childModel.ResourceName = childModel.ChildResourceName + } + childModel.RelationshipResourceName = GetResourceName(childModel.RelationshipClass, definitions) + childModel.Children = SetChildClassNames(definitions, childModel.Children) + + childMap[childName] = childModel + } + return childMap +} + func (m *Model) SetClassInclude() { if classDetails, ok := m.Definitions.Classes[m.PkgName]; ok { for key, value := range classDetails.(map[interface{}]interface{}) { @@ -923,6 +936,10 @@ func (m *Model) SetClassAllowDelete(classDetails interface{}) { } } +func (m *Model) SetParentName(classPkgName []string) { + m.ParentName = classPkgName[0] +} + // Determine if a class is allowed to be deleted as defined in the classes.yaml file // Flag created to ensure classes that only classes allowed to be deleted are deleted func (m *Model) SetResourceNotesAndWarnigns(classPkgName string, definitions Definitions) { diff --git a/gen/meta/commHttps.json b/gen/meta/commHttps.json new file mode 100644 index 000000000..a44c83aa6 --- /dev/null +++ b/gen/meta/commHttps.json @@ -0,0 +1,1798 @@ +{ + "comm:Https": { + "contains": { + "aaa:RbacAnnotation": "", + "comm:Cipher": "", + "comm:RsClientCertCA": "", + "comm:RsKeyRing": "", + "comm:RtCpmCommHttps": "", + "comm:WebConnAg15min": "", + "comm:WebConnAg1d": "", + "comm:WebConnAg1h": "", + "comm:WebConnAg1mo": "", + "comm:WebConnAg1qtr": "", + "comm:WebConnAg1w": "", + "comm:WebConnAg1year": "", + "comm:WebConnAgHist15min": "", + "comm:WebConnAgHist1d": "", + "comm:WebConnAgHist1h": "", + "comm:WebConnAgHist1mo": "", + "comm:WebConnAgHist1qtr": "", + "comm:WebConnAgHist1w": "", + "comm:WebConnAgHist1year": "", + "comm:WebConnStatesAg15min": "", + "comm:WebConnStatesAg1d": "", + "comm:WebConnStatesAg1h": "", + "comm:WebConnStatesAg1mo": "", + "comm:WebConnStatesAg1qtr": "", + "comm:WebConnStatesAg1w": "", + "comm:WebConnStatesAg1year": "", + "comm:WebConnStatesAgHist15min": "", + "comm:WebConnStatesAgHist1d": "", + "comm:WebConnStatesAgHist1h": "", + "comm:WebConnStatesAgHist1mo": "", + "comm:WebConnStatesAgHist1qtr": "", + "comm:WebConnStatesAgHist1w": "", + "comm:WebConnStatesAgHist1year": "", + "comm:WebProxy": "", + "comm:WebReqAg15min": "", + "comm:WebReqAg1d": "", + "comm:WebReqAg1h": "", + "comm:WebReqAg1mo": "", + "comm:WebReqAg1qtr": "", + "comm:WebReqAg1w": "", + "comm:WebReqAg1year": "", + "comm:WebReqAgHist15min": "", + "comm:WebReqAgHist1d": "", + "comm:WebReqAgHist1h": "", + "comm:WebReqAgHist1mo": "", + "comm:WebReqAgHist1qtr": "", + "comm:WebReqAgHist1w": "", + "comm:WebReqAgHist1year": "", + "fault:Counts": "", + "fault:Delegate": "", + "fault:Inst": "", + "health:Inst": "", + "tag:Annotation": "", + "tag:Tag": "" + }, + "rnMap": { + "CDcommWebConnAg15min": "comm:WebConnAg15min", + "CDcommWebConnAg1d": "comm:WebConnAg1d", + "CDcommWebConnAg1h": "comm:WebConnAg1h", + "CDcommWebConnAg1mo": "comm:WebConnAg1mo", + "CDcommWebConnAg1qtr": "comm:WebConnAg1qtr", + "CDcommWebConnAg1w": "comm:WebConnAg1w", + "CDcommWebConnAg1year": "comm:WebConnAg1year", + "CDcommWebConnStatesAg15min": "comm:WebConnStatesAg15min", + "CDcommWebConnStatesAg1d": "comm:WebConnStatesAg1d", + "CDcommWebConnStatesAg1h": "comm:WebConnStatesAg1h", + "CDcommWebConnStatesAg1mo": "comm:WebConnStatesAg1mo", + "CDcommWebConnStatesAg1qtr": "comm:WebConnStatesAg1qtr", + "CDcommWebConnStatesAg1w": "comm:WebConnStatesAg1w", + "CDcommWebConnStatesAg1year": "comm:WebConnStatesAg1year", + "CDcommWebReqAg15min": "comm:WebReqAg15min", + "CDcommWebReqAg1d": "comm:WebReqAg1d", + "CDcommWebReqAg1h": "comm:WebReqAg1h", + "CDcommWebReqAg1mo": "comm:WebReqAg1mo", + "CDcommWebReqAg1qtr": "comm:WebReqAg1qtr", + "CDcommWebReqAg1w": "comm:WebReqAg1w", + "CDcommWebReqAg1year": "comm:WebReqAg1year", + "HDcommWebConnAg15min-": "comm:WebConnAgHist15min", + "HDcommWebConnAg1d-": "comm:WebConnAgHist1d", + "HDcommWebConnAg1h-": "comm:WebConnAgHist1h", + "HDcommWebConnAg1mo-": "comm:WebConnAgHist1mo", + "HDcommWebConnAg1qtr-": "comm:WebConnAgHist1qtr", + "HDcommWebConnAg1w-": "comm:WebConnAgHist1w", + "HDcommWebConnAg1year-": "comm:WebConnAgHist1year", + "HDcommWebConnStatesAg15min-": "comm:WebConnStatesAgHist15min", + "HDcommWebConnStatesAg1d-": "comm:WebConnStatesAgHist1d", + "HDcommWebConnStatesAg1h-": "comm:WebConnStatesAgHist1h", + "HDcommWebConnStatesAg1mo-": "comm:WebConnStatesAgHist1mo", + "HDcommWebConnStatesAg1qtr-": "comm:WebConnStatesAgHist1qtr", + "HDcommWebConnStatesAg1w-": "comm:WebConnStatesAgHist1w", + "HDcommWebConnStatesAg1year-": "comm:WebConnStatesAgHist1year", + "HDcommWebReqAg15min-": "comm:WebReqAgHist15min", + "HDcommWebReqAg1d-": "comm:WebReqAgHist1d", + "HDcommWebReqAg1h-": "comm:WebReqAgHist1h", + "HDcommWebReqAg1mo-": "comm:WebReqAgHist1mo", + "HDcommWebReqAg1qtr-": "comm:WebReqAgHist1qtr", + "HDcommWebReqAg1w-": "comm:WebReqAgHist1w", + "HDcommWebReqAg1year-": "comm:WebReqAgHist1year", + "annotationKey-": "tag:Annotation", + "cph-": "comm:Cipher", + "fault-": "fault:Inst", + "fd-": "fault:Delegate", + "fltCnts": "fault:Counts", + "health": "health:Inst", + "rbacDom-": "aaa:RbacAnnotation", + "rsKeyRing": "comm:RsKeyRing", + "rsclientCertCA": "comm:RsClientCertCA", + "rtpolCpmCommHttps-": "comm:RtCpmCommHttps", + "tagKey-": "tag:Tag", + "wp-": "comm:WebProxy" + }, + "identifiedBy": [ + + ], + "rnFormat": "https", + "containedBy": { + "comm:Pol": "" + }, + "superClasses": [ + "comm:Web", + "comm:Comp", + "pol:Comp", + "pol:Obj", + "naming:NamedObject" + ], + "subClasses": { + + }, + "relationFrom": { + "comm:RtCpmCommHttps": "pol:DefRelnHolder" + }, + "relationTo": { + "comm:RsClientCertCA": "pki:TP", + "comm:RsKeyRing": "pki:KeyRing" + }, + "dnFormats": [ + "uni/fabric/comm-{name}/https" + ], + "writeAccess": [ + "aaa", + "admin" + ], + "readAccess": [ + "aaa", + "admin", + "fabric-equipment" + ], + "faults": { + + }, + "events": { + "E4205022": "modification||comm:Https", + "E4211222": "creation||comm:Https", + "E4211223": "modification||comm:Https", + "E4211224": "deletion||comm:Https" + }, + "stats": { + "comm:WebConnAg15min": { + "comment": [ + "A class that represents the most current aggregated statistics for web connections in a 15 minute sampling interval. This class updates every 5 minutes." + ] + }, + "comm:WebConnAg1d": { + "comment": [ + "A class that represents the most current aggregated statistics for web connections in a 1 day sampling interval. This class updates every hour." + ] + }, + "comm:WebConnAg1h": { + "comment": [ + "A class that represents the most current aggregated statistics for web connections in a 1 hour sampling interval. This class updates every 15 minutes." + ] + }, + "comm:WebConnAg1mo": { + "comment": [ + "A class that represents the most current aggregated statistics for web connections in a 1 month sampling interval. This class updates every day." + ] + }, + "comm:WebConnAg1qtr": { + "comment": [ + "A class that represents the most current aggregated statistics for web connections in a 1 quarter sampling interval. This class updates every day." + ] + }, + "comm:WebConnAg1w": { + "comment": [ + "A class that represents the most current aggregated statistics for web connections in a 1 week sampling interval. This class updates every day." + ] + }, + "comm:WebConnAg1year": { + "comment": [ + "A class that represents the most current aggregated statistics for web connections in a 1 year sampling interval. This class updates every day." + ] + }, + "comm:WebConnAgHist15min": { + "comment": [ + "A class that represents historical aggregated statistics for web connections in a 15 minute sampling interval. This class updates every 5 minutes." + ] + }, + "comm:WebConnAgHist1d": { + "comment": [ + "A class that represents historical aggregated statistics for web connections in a 1 day sampling interval. This class updates every hour." + ] + }, + "comm:WebConnAgHist1h": { + "comment": [ + "A class that represents historical aggregated statistics for web connections in a 1 hour sampling interval. This class updates every 15 minutes." + ] + }, + "comm:WebConnAgHist1mo": { + "comment": [ + "A class that represents historical aggregated statistics for web connections in a 1 month sampling interval. This class updates every day." + ] + }, + "comm:WebConnAgHist1qtr": { + "comment": [ + "A class that represents historical aggregated statistics for web connections in a 1 quarter sampling interval. This class updates every day." + ] + }, + "comm:WebConnAgHist1w": { + "comment": [ + "A class that represents historical aggregated statistics for web connections in a 1 week sampling interval. This class updates every day." + ] + }, + "comm:WebConnAgHist1year": { + "comment": [ + "A class that represents historical aggregated statistics for web connections in a 1 year sampling interval. This class updates every day." + ] + }, + "comm:WebConnStatesAg15min": { + "comment": [ + "A class that represents the most current aggregated statistics for web connections state in a 15 minute sampling interval. This class updates every 5 minutes." + ] + }, + "comm:WebConnStatesAg1d": { + "comment": [ + "A class that represents the most current aggregated statistics for web connections state in a 1 day sampling interval. This class updates every hour." + ] + }, + "comm:WebConnStatesAg1h": { + "comment": [ + "A class that represents the most current aggregated statistics for web connections state in a 1 hour sampling interval. This class updates every 15 minutes." + ] + }, + "comm:WebConnStatesAg1mo": { + "comment": [ + "A class that represents the most current aggregated statistics for web connections state in a 1 month sampling interval. This class updates every day." + ] + }, + "comm:WebConnStatesAg1qtr": { + "comment": [ + "A class that represents the most current aggregated statistics for web connections state in a 1 quarter sampling interval. This class updates every day." + ] + }, + "comm:WebConnStatesAg1w": { + "comment": [ + "A class that represents the most current aggregated statistics for web connections state in a 1 week sampling interval. This class updates every day." + ] + }, + "comm:WebConnStatesAg1year": { + "comment": [ + "A class that represents the most current aggregated statistics for web connections state in a 1 year sampling interval. This class updates every day." + ] + }, + "comm:WebConnStatesAgHist15min": { + "comment": [ + "A class that represents historical aggregated statistics for web connections state in a 15 minute sampling interval. This class updates every 5 minutes." + ] + }, + "comm:WebConnStatesAgHist1d": { + "comment": [ + "A class that represents historical aggregated statistics for web connections state in a 1 day sampling interval. This class updates every hour." + ] + }, + "comm:WebConnStatesAgHist1h": { + "comment": [ + "A class that represents historical aggregated statistics for web connections state in a 1 hour sampling interval. This class updates every 15 minutes." + ] + }, + "comm:WebConnStatesAgHist1mo": { + "comment": [ + "A class that represents historical aggregated statistics for web connections state in a 1 month sampling interval. This class updates every day." + ] + }, + "comm:WebConnStatesAgHist1qtr": { + "comment": [ + "A class that represents historical aggregated statistics for web connections state in a 1 quarter sampling interval. This class updates every day." + ] + }, + "comm:WebConnStatesAgHist1w": { + "comment": [ + "A class that represents historical aggregated statistics for web connections state in a 1 week sampling interval. This class updates every day." + ] + }, + "comm:WebConnStatesAgHist1year": { + "comment": [ + "A class that represents historical aggregated statistics for web connections state in a 1 year sampling interval. This class updates every day." + ] + }, + "comm:WebReqAg15min": { + "comment": [ + "A class that represents the most current aggregated statistics for web requests in a 15 minute sampling interval. This class updates every 5 minutes." + ] + }, + "comm:WebReqAg1d": { + "comment": [ + "A class that represents the most current aggregated statistics for web requests in a 1 day sampling interval. This class updates every hour." + ] + }, + "comm:WebReqAg1h": { + "comment": [ + "A class that represents the most current aggregated statistics for web requests in a 1 hour sampling interval. This class updates every 15 minutes." + ] + }, + "comm:WebReqAg1mo": { + "comment": [ + "A class that represents the most current aggregated statistics for web requests in a 1 month sampling interval. This class updates every day." + ] + }, + "comm:WebReqAg1qtr": { + "comment": [ + "A class that represents the most current aggregated statistics for web requests in a 1 quarter sampling interval. This class updates every day." + ] + }, + "comm:WebReqAg1w": { + "comment": [ + "A class that represents the most current aggregated statistics for web requests in a 1 week sampling interval. This class updates every day." + ] + }, + "comm:WebReqAg1year": { + "comment": [ + "A class that represents the most current aggregated statistics for web requests in a 1 year sampling interval. This class updates every day." + ] + }, + "comm:WebReqAgHist15min": { + "comment": [ + "A class that represents historical aggregated statistics for web requests in a 15 minute sampling interval. This class updates every 5 minutes." + ] + }, + "comm:WebReqAgHist1d": { + "comment": [ + "A class that represents historical aggregated statistics for web requests in a 1 day sampling interval. This class updates every hour." + ] + }, + "comm:WebReqAgHist1h": { + "comment": [ + "A class that represents historical aggregated statistics for web requests in a 1 hour sampling interval. This class updates every 15 minutes." + ] + }, + "comm:WebReqAgHist1mo": { + "comment": [ + "A class that represents historical aggregated statistics for web requests in a 1 month sampling interval. This class updates every day." + ] + }, + "comm:WebReqAgHist1qtr": { + "comment": [ + "A class that represents historical aggregated statistics for web requests in a 1 quarter sampling interval. This class updates every day." + ] + }, + "comm:WebReqAgHist1w": { + "comment": [ + "A class that represents historical aggregated statistics for web requests in a 1 week sampling interval. This class updates every day." + ] + }, + "comm:WebReqAgHist1year": { + "comment": [ + "A class that represents historical aggregated statistics for web requests in a 1 year sampling interval. This class updates every day." + ] + } + }, + "versions": "1.0(1e)-", + "isAbstract": false, + "isConfigurable": true, + "isContextRoot": false, + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false, + "isEncrypted": false, + "isExportable": true, + "isPersistent": true, + "isSubjectToQuota": false, + "isObservable": true, + "hasStats": true, + "isStat": false, + "isFaultable": true, + "isDomainable": false, + "isHealthScorable": true, + "shouldCollectHealthStats": false, + "healthCollectionSource": "faults", + "hasEventRules": false, + "abstractionLayer": "ambiguous", + "apicNxProcessing": false, + "monitoringPolicySource": "Parent", + "isCreatableDeletable": "never", + "platformFlavors": [ + + ], + "classId": "1578", + "className": "Https", + "classPkg": "comm", + "featureTag": "", + "moCategory": "Regular", + "label": "HTTP SSL Configuration", + "comment": [ + "HTTPS" + ], + "properties": { + "accessControlAllowCredential": { + "versions": "2.3(1e)-", + "isConfigurable": true, + "propGlobalId": "33388", + "propLocalId": "7960", + "label": "accessControlAllowCredential", + "baseType": "scalar:Enum8", + "modelType": "comm:AllowCredentialState", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "disabled", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "2", "localName": "disabled", + "platformFlavors": [ + + ], + "label": "Disabled "}, + { "value": "1", "localName": "enabled", + "platformFlavors": [ + + ], + "label": "Enabled "} + ], + "default": "disabled", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "accessControlAllowOrigins": { + "versions": "1.1(1j)-", + "comment": [ + "" + ], + "isConfigurable": true, + "propGlobalId": "17866", + "propLocalId": "4636", + "label": "accessControlAllowOrigins", + "baseType": "string:Basic", + "modelType": "comm:UrlList", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 256, + "regexs": [ + {"regex" : "^[a-zA-Z0-9-_:/.,\\*\\s]+$", "type": "include"} + ] + } + ], + "validValues": [ + { "value": "", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "} + ], + "default": "", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "adminSt": { + "versions": "1.0(1e)-", + "comment": [ + "The state of HTTPS communication service. This can be enabled or disabled." + ], + "isConfigurable": true, + "propGlobalId": "1298", + "propLocalId": "46", + "label": "Admin State", + "baseType": "scalar:Enum8", + "modelType": "comm:AdminState", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": true, + "isLike": false, + "validValues": [ + { "value": "enabled", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "2", "localName": "disabled", + "platformFlavors": [ + + ], + "label": "Disabled "}, + { "value": "1", "localName": "enabled", + "platformFlavors": [ + + ], + "label": "Enabled "} + ], + "default": "enabled", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "annotation": { + "versions": "3.2(1l)-", + "comment": [ + "User annotation. Suggested format orchestrator:value" + ], + "isConfigurable": true, + "propGlobalId": "37532", + "propLocalId": "8719", + "label": "Annotation", + "baseType": "string:Basic", + "modelType": "mo:Annotation", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 128, + "regexs": [ + {"regex" : "^[a-zA-Z0-9_.:-]+$", "type": "include"} + ] + } + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "childAction": { + "versions": "1.0(1e)-", + "comment": [ + "Delete or ignore. For internal use only." + ], + "isConfigurable": false, + "propGlobalId": "4", + "propLocalId": "5", + "label": "childAction", + "baseType": "scalar:Bitmask32", + "modelType": "mo:ModificationChildAction", + "needsPropDelimiters": false, + "uitype": "bitmask", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "16384", "localName": "deleteAll", + "platformFlavors": [ + + ], + "label": "Delete All "}, + { "value": "8192", "localName": "deleteNonPresent", + "platformFlavors": [ + + ], + "label": "Delete Non Present "}, + { "value": "4096", "localName": "ignore", + "platformFlavors": [ + + ], + "label": "Ignore "} + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "cliOnlyMode": { + "versions": "4.1(1i)-", + "isConfigurable": true, + "propGlobalId": "47672", + "propLocalId": "10837", + "label": "CLI only mode", + "baseType": "scalar:Enum8", + "modelType": "comm:CliOnlyMode", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "disabled", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "2", "localName": "disabled", + "platformFlavors": [ + + ], + "label": "Disabled "}, + { "value": "1", "localName": "enabled", + "platformFlavors": [ + + ], + "label": "Enabled "} + ], + "default": "disabled", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "clientCertAuthState": { + "versions": "4.0(1h)-", + "isConfigurable": true, + "propGlobalId": "42733", + "propLocalId": "9258", + "label": "Client Cert Auth State", + "baseType": "scalar:Enum8", + "modelType": "comm:AdminState", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "disabled", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "2", "localName": "disabled", + "platformFlavors": [ + + ], + "label": "Disabled "}, + { "value": "1", "localName": "enabled", + "platformFlavors": [ + + ], + "label": "Enabled "} + ], + "default": "disabled", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "descr": { + "versions": "1.0(1e)-", + "comment": [ + "Specifies the description of a policy component." + ], + "isConfigurable": true, + "propGlobalId": "5582", + "propLocalId": "28", + "label": "Description", + "baseType": "string:Basic", + "modelType": "naming:Descr", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": true, + "likeProp": "naming:Described:descr", + "validators": [ + {"min" : 0, "max": 128, + "regexs": [ + {"regex" : "^[a-zA-Z0-9\\\\!#$%()*,-./:;@ _{|}~?&+]+$", "type": "include"} + ] + } + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "dhParam": { + "versions": "1.2(2g)-", + "isConfigurable": true, + "propGlobalId": "24294", + "propLocalId": "5842", + "label": "DH Parameter", + "baseType": "scalar:Enum8", + "modelType": "comm:DHParam", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "1", "localName": "1024", + "platformFlavors": [ + + ], + "label": "1024 "}, + { "value": "2", "localName": "2048", + "platformFlavors": [ + + ], + "label": "2048 "}, + { "value": "3", "localName": "4096", + "platformFlavors": [ + + ], + "label": "4096 "}, + { "value": "none", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "0", "localName": "none", + "platformFlavors": [ + + ], + "label": "None "} + ], + "default": "none", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": true, + "isHidden": false + }, + "dn": { + "versions": "1.0(1e)-", + "comment": [ + "A tag or metadata is a non-hierarchical keyword or term assigned to the fabric module." + ], + "isConfigurable": false, + "propGlobalId": "1", + "propLocalId": "2", + "label": "dn", + "baseType": "reference:BinRef", + "modelType": "reference:BinRef", + "needsPropDelimiters": true, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "extMngdBy": { + "versions": "3.2(1l)-", + "comment": [ + "Indicates which orchestrator is managing this MO" + ], + "isConfigurable": false, + "propGlobalId": "39671", + "propLocalId": "8023", + "label": "Managed By", + "baseType": "scalar:Bitmask32", + "modelType": "mo:ExtMngdByType", + "needsPropDelimiters": false, + "uitype": "bitmask", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "undefined", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "1", "localName": "msc", + "platformFlavors": [ + + ], + "label": "MSC "}, + { "value": "0", "localName": "undefined", + "platformFlavors": [ + + ], + "label": "Undefined "} + ], + "default": "undefined", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "globalThrottleRate": { + "versions": "4.2(1i)-", + "isConfigurable": true, + "propGlobalId": "52997", + "propLocalId": "12189", + "label": "The maximum MO api calls allowed per unit time", + "baseType": "scalar:Uint32", + "modelType": "scalar:Uint32", + "needsPropDelimiters": false, + "uitype": "number", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 1, "max": 10000 } + ], + "validValues": [ + { "value": "10000", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "} + ], + "default": 10000, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "globalThrottleSt": { + "versions": "4.2(1i)-", + "isConfigurable": true, + "propGlobalId": "52996", + "propLocalId": "12188", + "label": "Throttle state for all clients without tag0 in header", + "baseType": "scalar:Enum8", + "modelType": "comm:AdminState", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "disabled", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "2", "localName": "disabled", + "platformFlavors": [ + + ], + "label": "Disabled "}, + { "value": "1", "localName": "enabled", + "platformFlavors": [ + + ], + "label": "Enabled "} + ], + "default": "disabled", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "globalThrottleUnit": { + "versions": "4.2(1i)-", + "isConfigurable": true, + "propGlobalId": "52998", + "propLocalId": "12190", + "label": "Unit of rate limit", + "baseType": "string:Basic", + "modelType": "comm:RateUnitType", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"regex" : "^[r]/[ms]$", "type": "include"} + ], + "validValues": [ + { "value": "r/s", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "} + ], + "default": "r/s", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "lcOwn": { + "versions": "1.0(1e)-", + "comment": [ + "A value that indicates how this object was created. For internal use only." + ], + "isConfigurable": false, + "propGlobalId": "9", + "propLocalId": "9", + "label": "lcOwn", + "baseType": "scalar:Enum8", + "modelType": "mo:Owner", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "local", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "4", "localName": "implicit", + "platformFlavors": [ + + ], + "label": "Implicit "}, + { "value": "0", "localName": "local", + "platformFlavors": [ + + ], + "label": "Local "}, + { "value": "1", "localName": "policy", + "platformFlavors": [ + + ], + "label": "Policy "}, + { "value": "2", "localName": "replica", + "platformFlavors": [ + + ], + "label": "Replica "}, + { "value": "3", "localName": "resolveOnBehalf", + "platformFlavors": [ + + ], + "label": "Resolved On Behalf "} + ], + "default": "local", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "maxRequestStatusCount": { + "versions": "1.1(1j)-", + "isConfigurable": true, + "propGlobalId": "19814", + "propLocalId": "5134", + "label": "The maximum number of request status objects to keep", + "baseType": "scalar:Uint32", + "modelType": "scalar:Uint32", + "needsPropDelimiters": false, + "uitype": "number", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 1024 } + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "modTs": { + "versions": "1.0(1e)-", + "comment": [ + "The time when this object was last modified." + ], + "isConfigurable": false, + "propGlobalId": "7", + "propLocalId": "7", + "label": "modTs", + "baseType": "scalar:Date", + "modelType": "mo:TStamp", + "needsPropDelimiters": false, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "never", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "0", "localName": "never", + "platformFlavors": [ + + ], + "label": "Never "} + ], + "default": "never", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "monPolDn": { + "versions": "1.0(1e)-", + "comment": [ + "The monitoring policy attached to this observable object." + ], + "isConfigurable": false, + "propGlobalId": "14145", + "propLocalId": "228", + "label": "Monitoring Policy", + "baseType": "reference:BinRef", + "modelType": "reference:BinRef", + "needsPropDelimiters": true, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "name": { + "versions": "1.0(1e)-", + "comment": [ + "null" + ], + "isConfigurable": true, + "propGlobalId": "1296", + "propLocalId": "13", + "label": "Name", + "baseType": "string:Basic", + "modelType": "naming:Name", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": true, + "isLike": false, + "validators": [ + {"min" : 0, "max": 64, + "regexs": [ + {"regex" : "^[a-zA-Z0-9_.:-]+$", "type": "include"} + ] + } + ], + "validValues": [ + { "value": "https", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "} + ], + "default": "https", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "nameAlias": { + "versions": "2.2(1k)-", + "isConfigurable": true, + "propGlobalId": "28417", + "propLocalId": "6719", + "label": "Display Name", + "baseType": "string:Basic", + "modelType": "naming:NameAlias", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 63, + "regexs": [ + {"regex" : "^[a-zA-Z0-9_.-]+$", "type": "include"} + ] + } + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "nodeExporter": { + "versions": "5.2(3e)-", + "isConfigurable": true, + "propGlobalId": "65281", + "propLocalId": "14483", + "label": "Node Exporter service", + "baseType": "scalar:Enum8", + "modelType": "comm:NodeExporter", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "disabled", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "2", "localName": "disabled", + "platformFlavors": [ + + ], + "label": "Disabled "}, + { "value": "1", "localName": "enabled", + "platformFlavors": [ + + ], + "label": "Enabled "} + ], + "default": "disabled", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "port": { + "versions": "1.0(1e)-", + "comment": [ + "The port used for HTTPS communication service." + ], + "isConfigurable": true, + "propGlobalId": "1297", + "propLocalId": "127", + "label": "Port", + "baseType": "scalar:Uint32", + "modelType": "comm:Port", + "needsPropDelimiters": false, + "uitype": "number", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": true, + "isLike": false, + "validators": [ + {"min" : 1, "max": 65535 } + ], + "validValues": [ + { "value": "443", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "} + ], + "default": 443, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "proto": { + "versions": "1.0(1e)-", + "comment": [ + "The list of protocols to match." + ], + "isConfigurable": false, + "propGlobalId": "1289", + "propLocalId": "144", + "label": "proto", + "baseType": "scalar:Enum8", + "modelType": "comm:Protocol", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": true, + "isLike": false, + "validValues": [ + { "value": "3", "localName": "all", + "platformFlavors": [ + + ], + "label": "All "}, + { "value": "tcp", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "0", "localName": "none", + "platformFlavors": [ + + ], + "label": "None "}, + { "value": "1", "localName": "tcp", + "platformFlavors": [ + + ], + "label": "tcp "}, + { "value": "2", "localName": "udp", + "platformFlavors": [ + + ], + "label": "udp "} + ], + "default": "tcp", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "referer": { + "versions": "6.0(2h)-", + "isConfigurable": true, + "propGlobalId": "69126", + "propLocalId": "15056", + "label": "Allowed HTTP referer space separated list", + "baseType": "string:Basic", + "modelType": "string:Basic", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 512 } + ], + "validValues": [ + { "value": "", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "} + ], + "default": "", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "rn": { + "versions": "1.0(1e)-", + "comment": [ + "Identifies an object from its siblings within the context of its parent object. The distinguished name contains a sequence of relative names." + ], + "isConfigurable": false, + "propGlobalId": "2", + "propLocalId": "3", + "label": "rn", + "baseType": "reference:BinRN", + "modelType": "reference:BinRN", + "needsPropDelimiters": true, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "serverHeader": { + "versions": "5.2(1g)-", + "isConfigurable": true, + "propGlobalId": "63694", + "propLocalId": "13996", + "label": "Server Header", + "baseType": "scalar:Enum8", + "modelType": "comm:ServerHeader", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "enabled", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "2", "localName": "disabled", + "platformFlavors": [ + + ], + "label": "Disabled "}, + { "value": "1", "localName": "enabled", + "platformFlavors": [ + + ], + "label": "Enabled "} + ], + "default": "enabled", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "sslProtocols": { + "versions": "1.1(1j)-", + "comment": [ + "The Secure Socket Layer (SSL) protocol." + ], + "isConfigurable": true, + "propGlobalId": "18247", + "propLocalId": "4711", + "label": "SSL Protocols", + "baseType": "scalar:Bitmask64", + "modelType": "comm:SslProtocolTypes", + "needsPropDelimiters": false, + "uitype": "bitmask", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "1", "localName": "TLSv1", + "platformFlavors": [ + + ], + "label": "TLSv1 "}, + { "value": "2", "localName": "TLSv1.1", + "platformFlavors": [ + + ], + "label": "TLSv1.1 "}, + { "value": "4", "localName": "TLSv1.2", + "platformFlavors": [ + + ], + "label": "TLSv1.2 "}, + { "value": "8", "localName": "TLSv1.3", + "platformFlavors": [ + + ], + "label": "TLSv1.3 "}, + { "value": "TLSv1.1,TLSv1.2", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "} + ], + "default": "TLSv1.1,TLSv1.2", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "status": { + "versions": "1.0(1e)-", + "comment": [ + "The upgrade status. This property is for internal use only." + ], + "isConfigurable": false, + "propGlobalId": "3", + "propLocalId": "4", + "label": "status", + "baseType": "scalar:Bitmask32", + "modelType": "mo:ModificationStatus", + "needsPropDelimiters": false, + "uitype": "bitmask", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "2", "localName": "created", + "platformFlavors": [ + + ], + "comment": [ + "In a setter method: specifies that an object should be created. An error is returned if the object already exists. \nIn the return value of a setter method: indicates that an object has been created. \n" + ], + "label": "Created "}, + { "value": "8", "localName": "deleted", + "platformFlavors": [ + + ], + "comment": [ + "In a setter method: specifies that an object should be deleted. \nIn the return value of a setter method: indicates that an object has been deleted.\n" + ], + "label": "Deleted "}, + { "value": "4", "localName": "modified", + "platformFlavors": [ + + ], + "comment": [ + "In a setter method: specifies that an object should be modified \nIn the return value of a setter method: indicates that an object has been modified.\n" + ], + "label": "Modified "} + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "throttleRate": { + "versions": "3.1(1i)-", + "isConfigurable": true, + "propGlobalId": "36782", + "propLocalId": "8597", + "label": "The maximum login/refresh allowed per second", + "baseType": "scalar:Uint32", + "modelType": "scalar:Uint32", + "needsPropDelimiters": false, + "uitype": "number", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 1, "max": 100 } + ], + "validValues": [ + { "value": "2", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "} + ], + "default": 2, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "throttleSt": { + "versions": "3.1(1i)-", + "isConfigurable": true, + "propGlobalId": "36781", + "propLocalId": "8596", + "label": "Login/refresh throttle state", + "baseType": "scalar:Enum8", + "modelType": "comm:AdminState", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "enabled", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "2", "localName": "disabled", + "platformFlavors": [ + + ], + "label": "Disabled "}, + { "value": "1", "localName": "enabled", + "platformFlavors": [ + + ], + "label": "Enabled "} + ], + "default": "enabled", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "uid": { + "versions": "1.0(1e)-", + "comment": [ + "A unique identifier for this object." + ], + "isConfigurable": false, + "propGlobalId": "8", + "propLocalId": "8", + "label": "uid", + "baseType": "scalar:Uint16", + "modelType": "scalar:Uint16", + "needsPropDelimiters": false, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "userdom": { + "versions": "5.0(1k)-", + "isConfigurable": true, + "propGlobalId": "60657", + "propLocalId": "13244", + "label": "userdom", + "baseType": "string:Basic", + "modelType": "mo:UserDomType", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 1024, + "regexs": [ + {"regex" : "^[a-zA-Z0-9_.:-]+$", "type": "include"} + ] + } + ], + "validValues": [ + { "value": "all", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "} + ], + "default": "all", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "visoreAccess": { + "versions": "3.1(1i)-", + "isConfigurable": true, + "propGlobalId": "35417", + "propLocalId": "8263", + "label": "Visore Access", + "baseType": "scalar:Enum8", + "modelType": "comm:VisoreAccess", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "enabled", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "2", "localName": "disabled", + "platformFlavors": [ + + ], + "label": "Disabled "}, + { "value": "1", "localName": "enabled", + "platformFlavors": [ + + ], + "label": "Enabled "} + ], + "default": "enabled", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + } + } + } +} diff --git a/gen/meta/commPol.json b/gen/meta/commPol.json new file mode 100644 index 000000000..9a0f3325d --- /dev/null +++ b/gen/meta/commPol.json @@ -0,0 +1,800 @@ +{ + "comm:Pol": { + "contains": { + "aaa:RbacAnnotation": "", + "comm:ApiRespTime": "", + "comm:Http": "", + "comm:Https": "", + "comm:Reconfig": "", + "comm:RtCommPol": "", + "comm:RtPol": "", + "comm:RtResPol": "", + "comm:RtWebCommDefault": "", + "comm:RtWebCommPolRel": "", + "comm:Setup": "", + "comm:Shellinabox": "", + "comm:Ssh": "", + "comm:Telnet": "", + "fault:Counts": "", + "fault:Delegate": "", + "health:Inst": "", + "tag:Annotation": "", + "tag:Tag": "" + }, + "rnMap": { + "annotationKey-": "tag:Annotation", + "apiResp": "comm:ApiRespTime", + "fd-": "fault:Delegate", + "fltCnts": "fault:Counts", + "health": "health:Inst", + "http": "comm:Http", + "https": "comm:Https", + "rbacDom-": "aaa:RbacAnnotation", + "reconfig": "comm:Reconfig", + "rtaaaPol-": "comm:RtPol", + "rtfabricCommPol-": "comm:RtCommPol", + "rtfabricResPol-": "comm:RtResPol", + "rtwebCommDefault-": "comm:RtWebCommDefault", + "rtwebCommPolRel": "comm:RtWebCommPolRel", + "setup": "comm:Setup", + "shellinabox": "comm:Shellinabox", + "ssh": "comm:Ssh", + "tagKey-": "tag:Tag", + "telnet": "comm:Telnet" + }, + "identifiedBy": [ + "name" + ], + "rnFormat": "comm-{name}", + "containedBy": { + "fabric:Inst": "" + }, + "superClasses": [ + "pol:Def", + "pol:Obj", + "naming:NamedObject" + ], + "subClasses": { + + }, + "relationFrom": { + "comm:RtCommPol": "fabric:PodPGrp", + "comm:RtPol": "aaa:SecRelnHolder", + "comm:RtResPol": "fabric:SecRelnHolder", + "comm:RtWebCommDefault": "comm:WebPolCont", + "comm:RtWebCommPolRel": "comm:WebPolCont" + }, + "relationTo": { + + }, + "dnFormats": [ + "uni/fabric/comm-{name}" + ], + "writeAccess": [ + "aaa", + "admin" + ], + "readAccess": [ + "aaa", + "admin", + "fabric-connectivity", + "fabric-equipment", + "fabric-protocol" + ], + "faults": { + + }, + "events": { + "E4211225": "creation||comm:Pol", + "E4211226": "modification||comm:Pol", + "E4211227": "deletion||comm:Pol" + }, + "stats": { + + }, + "versions": "1.0(1e)-", + "isAbstract": false, + "isConfigurable": true, + "isContextRoot": false, + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false, + "isEncrypted": false, + "isExportable": true, + "isPersistent": true, + "isSubjectToQuota": false, + "isObservable": true, + "hasStats": false, + "isStat": false, + "isFaultable": false, + "isDomainable": false, + "isHealthScorable": true, + "shouldCollectHealthStats": false, + "healthCollectionSource": "faults", + "hasEventRules": false, + "abstractionLayer": "ambiguous", + "apicNxProcessing": false, + "monitoringPolicySource": "Parent", + "isCreatableDeletable": "always", + "platformFlavors": [ + + ], + "classId": "1572", + "className": "Pol", + "classPkg": "comm", + "featureTag": "", + "moCategory": "Regular", + "label": "Communication Policy", + "comment": [ + "The communication policy contains the service configuration for various services." + ], + "properties": { + "annotation": { + "versions": "3.2(1l)-", + "comment": [ + "User annotation. Suggested format orchestrator:value" + ], + "isConfigurable": true, + "propGlobalId": "37529", + "propLocalId": "8719", + "label": "Annotation", + "baseType": "string:Basic", + "modelType": "mo:Annotation", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 128, + "regexs": [ + {"regex" : "^[a-zA-Z0-9_.:-]+$", "type": "include"} + ] + } + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "childAction": { + "versions": "1.0(1e)-", + "comment": [ + "Delete or ignore. For internal use only." + ], + "isConfigurable": false, + "propGlobalId": "4", + "propLocalId": "5", + "label": "childAction", + "baseType": "scalar:Bitmask32", + "modelType": "mo:ModificationChildAction", + "needsPropDelimiters": false, + "uitype": "bitmask", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "16384", "localName": "deleteAll", + "platformFlavors": [ + + ], + "label": "Delete All "}, + { "value": "8192", "localName": "deleteNonPresent", + "platformFlavors": [ + + ], + "label": "Delete Non Present "}, + { "value": "4096", "localName": "ignore", + "platformFlavors": [ + + ], + "label": "Ignore "} + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "descr": { + "versions": "1.0(1e)-", + "comment": [ + "Specifies a description of the policy definition." + ], + "isConfigurable": true, + "propGlobalId": "5579", + "propLocalId": "28", + "label": "Description", + "baseType": "string:Basic", + "modelType": "naming:Descr", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": true, + "likeProp": "naming:Described:descr", + "validators": [ + {"min" : 0, "max": 128, + "regexs": [ + {"regex" : "^[a-zA-Z0-9\\\\!#$%()*,-./:;@ _{|}~?&+]+$", "type": "include"} + ] + } + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "dn": { + "versions": "1.0(1e)-", + "comment": [ + "A tag or metadata is a non-hierarchical keyword or term assigned to the fabric module." + ], + "isConfigurable": false, + "propGlobalId": "1", + "propLocalId": "2", + "label": "dn", + "baseType": "reference:BinRef", + "modelType": "reference:BinRef", + "needsPropDelimiters": true, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "extMngdBy": { + "versions": "3.2(1l)-", + "comment": [ + "Indicates which orchestrator is managing this MO" + ], + "isConfigurable": false, + "propGlobalId": "39668", + "propLocalId": "8023", + "label": "Managed By", + "baseType": "scalar:Bitmask32", + "modelType": "mo:ExtMngdByType", + "needsPropDelimiters": false, + "uitype": "bitmask", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "undefined", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "1", "localName": "msc", + "platformFlavors": [ + + ], + "label": "MSC "}, + { "value": "0", "localName": "undefined", + "platformFlavors": [ + + ], + "label": "Undefined "} + ], + "default": "undefined", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "lcOwn": { + "versions": "1.0(1e)-", + "comment": [ + "A value that indicates how this object was created. For internal use only." + ], + "isConfigurable": false, + "propGlobalId": "9", + "propLocalId": "9", + "label": "lcOwn", + "baseType": "scalar:Enum8", + "modelType": "mo:Owner", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "local", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "4", "localName": "implicit", + "platformFlavors": [ + + ], + "label": "Implicit "}, + { "value": "0", "localName": "local", + "platformFlavors": [ + + ], + "label": "Local "}, + { "value": "1", "localName": "policy", + "platformFlavors": [ + + ], + "label": "Policy "}, + { "value": "2", "localName": "replica", + "platformFlavors": [ + + ], + "label": "Replica "}, + { "value": "3", "localName": "resolveOnBehalf", + "platformFlavors": [ + + ], + "label": "Resolved On Behalf "} + ], + "default": "local", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "modTs": { + "versions": "1.0(1e)-", + "comment": [ + "The time when this object was last modified." + ], + "isConfigurable": false, + "propGlobalId": "7", + "propLocalId": "7", + "label": "modTs", + "baseType": "scalar:Date", + "modelType": "mo:TStamp", + "needsPropDelimiters": false, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "never", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "0", "localName": "never", + "platformFlavors": [ + + ], + "label": "Never "} + ], + "default": "never", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "monPolDn": { + "versions": "1.0(1e)-", + "comment": [ + "The monitoring policy attached to this observable object." + ], + "isConfigurable": false, + "propGlobalId": "14144", + "propLocalId": "228", + "label": "Monitoring Policy", + "baseType": "reference:BinRef", + "modelType": "reference:BinRef", + "needsPropDelimiters": true, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "name": { + "versions": "1.0(1e)-", + "comment": [ + "The name of the policy. This name can be up to 64 alphanumeric characters. Note that you cannot change this name after the object has been saved." + ], + "isConfigurable": true, + "propGlobalId": "5905", + "propLocalId": "13", + "label": "Name", + "baseType": "string:Basic", + "modelType": "naming:Name", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": false, + "readOnly": false, + "isNaming": true, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": true, + "isLike": false, + "validators": [ + {"min" : 1, "max": 64, + "regexs": [ + {"regex" : "^[a-zA-Z0-9_.:-]+$", "type": "include"} + ] + } + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "nameAlias": { + "versions": "2.2(1k)-", + "isConfigurable": true, + "propGlobalId": "28417", + "propLocalId": "6719", + "label": "Display Name", + "baseType": "string:Basic", + "modelType": "naming:NameAlias", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 63, + "regexs": [ + {"regex" : "^[a-zA-Z0-9_.-]+$", "type": "include"} + ] + } + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "ownerKey": { + "versions": "1.0(1e)-", + "comment": [ + "The key for enabling clients to own their data for entity correlation." + ], + "isConfigurable": true, + "propGlobalId": "15230", + "propLocalId": "4100", + "label": "ownerKey", + "baseType": "string:Basic", + "modelType": "naming:Descr", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 128, + "regexs": [ + {"regex" : "^[a-zA-Z0-9\\\\!#$%()*,-./:;@ _{|}~?&+]+$", "type": "include"} + ] + } + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "ownerTag": { + "versions": "1.0(1e)-", + "comment": [ + "A tag for enabling clients to add their own data. For example, to indicate who created this object." + ], + "isConfigurable": true, + "propGlobalId": "15231", + "propLocalId": "4101", + "label": "ownerTag", + "baseType": "string:Basic", + "modelType": "naming:Descr", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 64, + "regexs": [ + {"regex" : "^[a-zA-Z0-9\\\\!#$%()*,-./:;@ _{|}~?&+]+$", "type": "include"} + ] + } + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "rn": { + "versions": "1.0(1e)-", + "comment": [ + "Identifies an object from its siblings within the context of its parent object. The distinguished name contains a sequence of relative names." + ], + "isConfigurable": false, + "propGlobalId": "2", + "propLocalId": "3", + "label": "rn", + "baseType": "reference:BinRN", + "modelType": "reference:BinRN", + "needsPropDelimiters": true, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "status": { + "versions": "1.0(1e)-", + "comment": [ + "The upgrade status. This property is for internal use only." + ], + "isConfigurable": false, + "propGlobalId": "3", + "propLocalId": "4", + "label": "status", + "baseType": "scalar:Bitmask32", + "modelType": "mo:ModificationStatus", + "needsPropDelimiters": false, + "uitype": "bitmask", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "2", "localName": "created", + "platformFlavors": [ + + ], + "comment": [ + "In a setter method: specifies that an object should be created. An error is returned if the object already exists. \nIn the return value of a setter method: indicates that an object has been created. \n" + ], + "label": "Created "}, + { "value": "8", "localName": "deleted", + "platformFlavors": [ + + ], + "comment": [ + "In a setter method: specifies that an object should be deleted. \nIn the return value of a setter method: indicates that an object has been deleted.\n" + ], + "label": "Deleted "}, + { "value": "4", "localName": "modified", + "platformFlavors": [ + + ], + "comment": [ + "In a setter method: specifies that an object should be modified \nIn the return value of a setter method: indicates that an object has been modified.\n" + ], + "label": "Modified "} + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "strictSecurityOnApicOOBSubnet": { + "isConfigurable": true, + "propGlobalId": "70760", + "propLocalId": "15519", + "label": "remove implicit access on apic oob from any apic OOB subnet IP", + "baseType": "scalar:Bool", + "modelType": "scalar:Bool", + "needsPropDelimiters": false, + "uitype": "boolean", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "false", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "false", "localName": "no", + "platformFlavors": [ + + ], + "label": "No "}, + { "value": "true", "localName": "yes", + "platformFlavors": [ + + ], + "label": "Yes "} + ], + "default": "false", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "uid": { + "versions": "1.0(1e)-", + "comment": [ + "A unique identifier for this object." + ], + "isConfigurable": false, + "propGlobalId": "8", + "propLocalId": "8", + "label": "uid", + "baseType": "scalar:Uint16", + "modelType": "scalar:Uint16", + "needsPropDelimiters": false, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "userdom": { + "versions": "5.0(1k)-", + "isConfigurable": true, + "propGlobalId": "60657", + "propLocalId": "13244", + "label": "userdom", + "baseType": "string:Basic", + "modelType": "mo:UserDomType", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 1024, + "regexs": [ + {"regex" : "^[a-zA-Z0-9_.:-]+$", "type": "include"} + ] + } + ], + "validValues": [ + { "value": "all", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "} + ], + "default": "all", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + } + } + } +} diff --git a/gen/meta/commRsClientCertCA.json b/gen/meta/commRsClientCertCA.json new file mode 100644 index 000000000..11dfd0982 --- /dev/null +++ b/gen/meta/commRsClientCertCA.json @@ -0,0 +1,912 @@ +{ + "comm:RsClientCertCA": { + "contains": { + "aaa:RbacAnnotation": "", + "fault:Counts": "", + "fault:Inst": "", + "health:Inst": "", + "tag:Annotation": "", + "tag:Tag": "" + }, + "rnMap": { + "annotationKey-": "tag:Annotation", + "fault-": "fault:Inst", + "fltCnts": "fault:Counts", + "health": "health:Inst", + "rbacDom-": "aaa:RbacAnnotation", + "tagKey-": "tag:Tag" + }, + "identifiedBy": [ + + ], + "rnFormat": "rsclientCertCA", + "containedBy": { + "comm:Https": "" + }, + "superClasses": [ + "reln:To", + "reln:Inst" + ], + "subClasses": { + + }, + "relationInfo": { + "type": "explicit", + "cardinality": "n-to-1", + "fromMo": "comm:Https", + "fromRelMo": "comm:RsClientCertCA", + "toMo": "pki:TP", + "toRelMo": "pki:RtClientCertCA", + "enforceable": true, + "resolvable": true + }, + "dnFormats": [ + "uni/fabric/comm-{name}/https/rsclientCertCA" + ], + "writeAccess": [ + "aaa", + "admin" + ], + "readAccess": [ + "aaa", + "admin", + "fabric-equipment" + ], + "faults": { + "F3138": "fltCommRsClientCertCAResolveFail" + }, + "events": { + "E4215646": "creation||comm:RsClientCertCA", + "E4215647": "modification||comm:RsClientCertCA", + "E4215648": "deletion||comm:RsClientCertCA" + }, + "stats": { + + }, + "versions": "4.0(1h)-", + "isAbstract": false, + "isConfigurable": true, + "isContextRoot": false, + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false, + "isEncrypted": false, + "isExportable": true, + "isPersistent": true, + "isSubjectToQuota": false, + "isObservable": true, + "hasStats": false, + "isStat": false, + "isFaultable": true, + "isDomainable": false, + "isHealthScorable": true, + "shouldCollectHealthStats": false, + "healthCollectionSource": "faults", + "hasEventRules": false, + "abstractionLayer": "regular", + "apicNxProcessing": false, + "monitoringPolicySource": "Parent", + "isCreatableDeletable": "always", + "platformFlavors": [ + + ], + "classId": "12375", + "className": "RsClientCertCA", + "classPkg": "comm", + "featureTag": "", + "moCategory": "RelationshipToLocal", + "label": "TP", + "properties": { + "annotation": { + "versions": "4.0(1h)-", + "comment": [ + "User annotation. Suggested format orchestrator:value" + ], + "isConfigurable": true, + "propGlobalId": "42750", + "propLocalId": "8719", + "label": "Annotation", + "baseType": "string:Basic", + "modelType": "mo:Annotation", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 128, + "regexs": [ + {"regex" : "^[a-zA-Z0-9_.:-]+$", "type": "include"} + ] + } + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "childAction": { + "versions": "1.0(1e)-", + "comment": [ + "Delete or ignore. For internal use only." + ], + "isConfigurable": false, + "propGlobalId": "4", + "propLocalId": "5", + "label": "childAction", + "baseType": "scalar:Bitmask32", + "modelType": "mo:ModificationChildAction", + "needsPropDelimiters": false, + "uitype": "bitmask", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "16384", "localName": "deleteAll", + "platformFlavors": [ + + ], + "label": "Delete All "}, + { "value": "8192", "localName": "deleteNonPresent", + "platformFlavors": [ + + ], + "label": "Delete Non Present "}, + { "value": "4096", "localName": "ignore", + "platformFlavors": [ + + ], + "label": "Ignore "} + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "dn": { + "versions": "1.0(1e)-", + "comment": [ + "A tag or metadata is a non-hierarchical keyword or term assigned to the fabric module." + ], + "isConfigurable": false, + "propGlobalId": "1", + "propLocalId": "2", + "label": "dn", + "baseType": "reference:BinRef", + "modelType": "reference:BinRef", + "needsPropDelimiters": true, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "extMngdBy": { + "versions": "4.0(1h)-", + "comment": [ + "Indicates which orchestrator is managing this MO" + ], + "isConfigurable": false, + "propGlobalId": "42751", + "propLocalId": "8023", + "label": "Managed By", + "baseType": "scalar:Bitmask32", + "modelType": "mo:ExtMngdByType", + "needsPropDelimiters": false, + "uitype": "bitmask", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "undefined", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "1", "localName": "msc", + "platformFlavors": [ + + ], + "label": "MSC "}, + { "value": "0", "localName": "undefined", + "platformFlavors": [ + + ], + "label": "Undefined "} + ], + "default": "undefined", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "forceResolve": { + "versions": "1.0(1e)-", + "comment": [ + "Whether the relation should force pull the target." + ], + "isConfigurable": false, + "propGlobalId": "107", + "propLocalId": "83", + "label": "Force Resolve", + "baseType": "scalar:Bool", + "modelType": "scalar:Bool", + "needsPropDelimiters": false, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "true", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "false", "localName": "no", + "platformFlavors": [ + + ], + "label": "No "}, + { "value": "true", "localName": "yes", + "platformFlavors": [ + + ], + "label": "Yes "} + ], + "default": "yes", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "lcOwn": { + "versions": "1.0(1e)-", + "comment": [ + "A value that indicates how this object was created. For internal use only." + ], + "isConfigurable": false, + "propGlobalId": "9", + "propLocalId": "9", + "label": "lcOwn", + "baseType": "scalar:Enum8", + "modelType": "mo:Owner", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "local", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "4", "localName": "implicit", + "platformFlavors": [ + + ], + "label": "Implicit "}, + { "value": "0", "localName": "local", + "platformFlavors": [ + + ], + "label": "Local "}, + { "value": "1", "localName": "policy", + "platformFlavors": [ + + ], + "label": "Policy "}, + { "value": "2", "localName": "replica", + "platformFlavors": [ + + ], + "label": "Replica "}, + { "value": "3", "localName": "resolveOnBehalf", + "platformFlavors": [ + + ], + "label": "Resolved On Behalf "} + ], + "default": "local", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "modTs": { + "versions": "1.0(1e)-", + "comment": [ + "The time when this object was last modified." + ], + "isConfigurable": false, + "propGlobalId": "7", + "propLocalId": "7", + "label": "modTs", + "baseType": "scalar:Date", + "modelType": "mo:TStamp", + "needsPropDelimiters": false, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "never", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "0", "localName": "never", + "platformFlavors": [ + + ], + "label": "Never "} + ], + "default": "never", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "monPolDn": { + "versions": "4.0(1h)-", + "comment": [ + "The monitoring policy attached to this observable object." + ], + "isConfigurable": false, + "propGlobalId": "42745", + "propLocalId": "228", + "label": "Monitoring Policy", + "baseType": "reference:BinRef", + "modelType": "reference:BinRef", + "needsPropDelimiters": true, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "rType": { + "versions": "1.0(1e)-", + "comment": [ + "Represents the type of resolver." + ], + "isConfigurable": false, + "propGlobalId": "106", + "propLocalId": "82", + "label": "Resolver Type", + "baseType": "scalar:Enum8", + "modelType": "reln:ResolverType", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "mo", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "3", "localName": "local", + "platformFlavors": [ + + ], + "label": "Local "}, + { "value": "1", "localName": "mo", + "platformFlavors": [ + + ], + "label": "MO "}, + { "value": "2", "localName": "service", + "platformFlavors": [ + + ], + "label": "Service "} + ], + "default": "mo", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "rn": { + "versions": "1.0(1e)-", + "comment": [ + "Identifies an object from its siblings within the context of its parent object. The distinguished name contains a sequence of relative names." + ], + "isConfigurable": false, + "propGlobalId": "2", + "propLocalId": "3", + "label": "rn", + "baseType": "reference:BinRN", + "modelType": "reference:BinRN", + "needsPropDelimiters": true, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "state": { + "versions": "1.0(1e)-", + "comment": [ + "Represents the state of the relationship." + ], + "isConfigurable": false, + "propGlobalId": "103", + "propLocalId": "26", + "label": "State", + "baseType": "scalar:Enum8", + "modelType": "reln:State", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "5", "localName": "cardinality-violation", + "platformFlavors": [ + + ], + "comment": [ + "cardinality violation - When relations are created such that\n they violate the cardinality, state of the relation would be\n set to this." + ], + "label": "Cardinality Violation "}, + { "value": "unformed", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "1", "localName": "formed", + "platformFlavors": [ + + ], + "comment": [ + "the relationship is formed with the target object" + ], + "label": "Formed "}, + { "value": "4", "localName": "invalid-target", + "platformFlavors": [ + + ], + "comment": [ + "invalid target DN" + ], + "label": "Invalid Target "}, + { "value": "2", "localName": "missing-target", + "platformFlavors": [ + + ], + "comment": [ + "target does not exist" + ], + "label": "Missing Target "}, + { "value": "0", "localName": "unformed", + "platformFlavors": [ + + ], + "comment": [ + "the relationship is not formed" + ], + "label": "Unformed "} + ], + "default": "unformed", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "stateQual": { + "versions": "1.0(1e)-", + "comment": [ + "Represents the state qualifier of the relationship." + ], + "isConfigurable": false, + "propGlobalId": "104", + "propLocalId": "80", + "label": "State Qualifier", + "baseType": "scalar:Enum8", + "modelType": "reln:StateQual", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "2", "localName": "default-target", + "platformFlavors": [ + + ], + "comment": [ + "target not specified, using default" + ], + "label": "Target Not Specified "}, + { "value": "none", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "1", "localName": "mismatch-target", + "platformFlavors": [ + + ], + "comment": [ + "target not found, using default" + ], + "label": "Target Not Found "}, + { "value": "0", "localName": "none", + "platformFlavors": [ + + ], + "comment": [ + "no issue" + ], + "label": "None "} + ], + "default": "none", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "status": { + "versions": "1.0(1e)-", + "comment": [ + "The upgrade status. This property is for internal use only." + ], + "isConfigurable": false, + "propGlobalId": "3", + "propLocalId": "4", + "label": "status", + "baseType": "scalar:Bitmask32", + "modelType": "mo:ModificationStatus", + "needsPropDelimiters": false, + "uitype": "bitmask", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "2", "localName": "created", + "platformFlavors": [ + + ], + "comment": [ + "In a setter method: specifies that an object should be created. An error is returned if the object already exists. \nIn the return value of a setter method: indicates that an object has been created. \n" + ], + "label": "Created "}, + { "value": "8", "localName": "deleted", + "platformFlavors": [ + + ], + "comment": [ + "In a setter method: specifies that an object should be deleted. \nIn the return value of a setter method: indicates that an object has been deleted.\n" + ], + "label": "Deleted "}, + { "value": "4", "localName": "modified", + "platformFlavors": [ + + ], + "comment": [ + "In a setter method: specifies that an object should be modified \nIn the return value of a setter method: indicates that an object has been modified.\n" + ], + "label": "Modified "} + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "tCl": { + "versions": "4.0(1h)-", + "comment": [ + "The class ID of the target object. This property is managed internally and should not be modified by the user." + ], + "isConfigurable": false, + "propGlobalId": "42742", + "propLocalId": "78", + "label": "Target Class", + "baseType": "scalar:Enum16", + "modelType": "reln:ClassId", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": true, + "isLike": false, + "validValues": [ + { "value": "1483", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "1483", "localName": "pkiTP", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "0", "localName": "unspecified", + "platformFlavors": [ + + ], + "label": "unspecified "} + ], + "default": "pkiTP", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "tDn": { + "versions": "4.0(1h)-", + "comment": [ + "The distinguished name of the target." + ], + "isConfigurable": true, + "propGlobalId": "50066", + "propLocalId": "77", + "label": "Target-dn", + "baseType": "reference:BinRef", + "modelType": "reln:Dn", + "needsPropDelimiters": true, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": true, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "tType": { + "versions": "1.0(1e)-", + "comment": [ + "The type of target." + ], + "isConfigurable": false, + "propGlobalId": "105", + "propLocalId": "81", + "label": "Target Type", + "baseType": "scalar:Enum8", + "modelType": "reln:TargetType", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "2", "localName": "all", + "platformFlavors": [ + + ], + "label": "All "}, + { "value": "mo", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "1", "localName": "mo", + "platformFlavors": [ + + ], + "label": "MO "}, + { "value": "0", "localName": "name", + "platformFlavors": [ + + ], + "label": "Name "} + ], + "default": "mo", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "uid": { + "versions": "1.0(1e)-", + "comment": [ + "A unique identifier for this object." + ], + "isConfigurable": false, + "propGlobalId": "8", + "propLocalId": "8", + "label": "uid", + "baseType": "scalar:Uint16", + "modelType": "scalar:Uint16", + "needsPropDelimiters": false, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "userdom": { + "versions": "5.0(1k)-", + "isConfigurable": true, + "propGlobalId": "60657", + "propLocalId": "13244", + "label": "userdom", + "baseType": "string:Basic", + "modelType": "mo:UserDomType", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 1024, + "regexs": [ + {"regex" : "^[a-zA-Z0-9_.:-]+$", "type": "include"} + ] + } + ], + "validValues": [ + { "value": "all", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "} + ], + "default": "all", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + } + } + } +} diff --git a/gen/meta/commRsKeyRing.json b/gen/meta/commRsKeyRing.json new file mode 100644 index 000000000..8dd9b1e6b --- /dev/null +++ b/gen/meta/commRsKeyRing.json @@ -0,0 +1,1010 @@ +{ + "comm:RsKeyRing": { + "contains": { + "aaa:RbacAnnotation": "", + "fault:Counts": "", + "fault:Inst": "", + "health:Inst": "", + "tag:Annotation": "", + "tag:Tag": "" + }, + "rnMap": { + "annotationKey-": "tag:Annotation", + "fault-": "fault:Inst", + "fltCnts": "fault:Counts", + "health": "health:Inst", + "rbacDom-": "aaa:RbacAnnotation", + "tagKey-": "tag:Tag" + }, + "identifiedBy": [ + + ], + "rnFormat": "rsKeyRing", + "containedBy": { + "comm:Https": "" + }, + "superClasses": [ + "pol:NToRef", + "reln:To", + "reln:Inst" + ], + "subClasses": { + + }, + "relationInfo": { + "type": "named", + "cardinality": "n-to-1", + "fromMo": "comm:Https", + "fromRelMo": "comm:RsKeyRing", + "toMo": "pki:KeyRing", + "toRelMo": "pki:RtKeyRing", + "enforceable": true, + "resolvable": true + }, + "dnFormats": [ + "uni/fabric/comm-{name}/https/rsKeyRing" + ], + "writeAccess": [ + "aaa", + "admin" + ], + "readAccess": [ + "aaa", + "admin", + "fabric-equipment" + ], + "faults": { + "F1399": "fltCommRsKeyRingResolveFail" + }, + "events": { + "E4211228": "creation||comm:RsKeyRing", + "E4211229": "modification||comm:RsKeyRing", + "E4211230": "deletion||comm:RsKeyRing" + }, + "stats": { + + }, + "versions": "1.0(1e)-", + "isAbstract": false, + "isConfigurable": true, + "isContextRoot": false, + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false, + "isEncrypted": false, + "isExportable": true, + "isPersistent": true, + "isSubjectToQuota": false, + "isObservable": true, + "hasStats": false, + "isStat": false, + "isFaultable": true, + "isDomainable": false, + "isHealthScorable": true, + "shouldCollectHealthStats": false, + "healthCollectionSource": "faults", + "hasEventRules": false, + "abstractionLayer": "regular", + "apicNxProcessing": false, + "monitoringPolicySource": "Parent", + "isCreatableDeletable": "never", + "platformFlavors": [ + + ], + "classId": "5530", + "className": "RsKeyRing", + "classPkg": "comm", + "featureTag": "", + "moCategory": "RelationshipToLocal", + "label": "Key Ring", + "comment": [ + "A source relation to a key ring." + ], + "properties": { + "annotation": { + "versions": "3.2(1l)-", + "comment": [ + "User annotation. Suggested format orchestrator:value" + ], + "isConfigurable": true, + "propGlobalId": "38117", + "propLocalId": "8719", + "label": "Annotation", + "baseType": "string:Basic", + "modelType": "mo:Annotation", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 128, + "regexs": [ + {"regex" : "^[a-zA-Z0-9_.:-]+$", "type": "include"} + ] + } + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "childAction": { + "versions": "1.0(1e)-", + "comment": [ + "Delete or ignore. For internal use only." + ], + "isConfigurable": false, + "propGlobalId": "4", + "propLocalId": "5", + "label": "childAction", + "baseType": "scalar:Bitmask32", + "modelType": "mo:ModificationChildAction", + "needsPropDelimiters": false, + "uitype": "bitmask", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "16384", "localName": "deleteAll", + "platformFlavors": [ + + ], + "label": "Delete All "}, + { "value": "8192", "localName": "deleteNonPresent", + "platformFlavors": [ + + ], + "label": "Delete Non Present "}, + { "value": "4096", "localName": "ignore", + "platformFlavors": [ + + ], + "label": "Ignore "} + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "dn": { + "versions": "1.0(1e)-", + "comment": [ + "A tag or metadata is a non-hierarchical keyword or term assigned to the fabric module." + ], + "isConfigurable": false, + "propGlobalId": "1", + "propLocalId": "2", + "label": "dn", + "baseType": "reference:BinRef", + "modelType": "reference:BinRef", + "needsPropDelimiters": true, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "extMngdBy": { + "versions": "3.2(1l)-", + "comment": [ + "Indicates which orchestrator is managing this MO" + ], + "isConfigurable": false, + "propGlobalId": "40256", + "propLocalId": "8023", + "label": "Managed By", + "baseType": "scalar:Bitmask32", + "modelType": "mo:ExtMngdByType", + "needsPropDelimiters": false, + "uitype": "bitmask", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "undefined", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "1", "localName": "msc", + "platformFlavors": [ + + ], + "label": "MSC "}, + { "value": "0", "localName": "undefined", + "platformFlavors": [ + + ], + "label": "Undefined "} + ], + "default": "undefined", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "forceResolve": { + "versions": "1.0(1e)-", + "comment": [ + "Whether the relation should force pull the target." + ], + "isConfigurable": false, + "propGlobalId": "107", + "propLocalId": "83", + "label": "Force Resolve", + "baseType": "scalar:Bool", + "modelType": "scalar:Bool", + "needsPropDelimiters": false, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "true", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "false", "localName": "no", + "platformFlavors": [ + + ], + "label": "No "}, + { "value": "true", "localName": "yes", + "platformFlavors": [ + + ], + "label": "Yes "} + ], + "default": "yes", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "lcOwn": { + "versions": "1.0(1e)-", + "comment": [ + "A value that indicates how this object was created. For internal use only." + ], + "isConfigurable": false, + "propGlobalId": "9", + "propLocalId": "9", + "label": "lcOwn", + "baseType": "scalar:Enum8", + "modelType": "mo:Owner", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "local", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "4", "localName": "implicit", + "platformFlavors": [ + + ], + "label": "Implicit "}, + { "value": "0", "localName": "local", + "platformFlavors": [ + + ], + "label": "Local "}, + { "value": "1", "localName": "policy", + "platformFlavors": [ + + ], + "label": "Policy "}, + { "value": "2", "localName": "replica", + "platformFlavors": [ + + ], + "label": "Replica "}, + { "value": "3", "localName": "resolveOnBehalf", + "platformFlavors": [ + + ], + "label": "Resolved On Behalf "} + ], + "default": "local", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "modTs": { + "versions": "1.0(1e)-", + "comment": [ + "The time when this object was last modified." + ], + "isConfigurable": false, + "propGlobalId": "7", + "propLocalId": "7", + "label": "modTs", + "baseType": "scalar:Date", + "modelType": "mo:TStamp", + "needsPropDelimiters": false, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "never", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "0", "localName": "never", + "platformFlavors": [ + + ], + "label": "Never "} + ], + "default": "never", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "monPolDn": { + "versions": "1.0(1e)-", + "comment": [ + "The monitoring policy attached to this observable object." + ], + "isConfigurable": false, + "propGlobalId": "16229", + "propLocalId": "228", + "label": "Monitoring Policy", + "baseType": "reference:BinRef", + "modelType": "reference:BinRef", + "needsPropDelimiters": true, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "rType": { + "versions": "1.0(1e)-", + "comment": [ + "Represents the type of resolver." + ], + "isConfigurable": false, + "propGlobalId": "106", + "propLocalId": "82", + "label": "Resolver Type", + "baseType": "scalar:Enum8", + "modelType": "reln:ResolverType", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "mo", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "3", "localName": "local", + "platformFlavors": [ + + ], + "label": "Local "}, + { "value": "1", "localName": "mo", + "platformFlavors": [ + + ], + "label": "MO "}, + { "value": "2", "localName": "service", + "platformFlavors": [ + + ], + "label": "Service "} + ], + "default": "mo", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "rn": { + "versions": "1.0(1e)-", + "comment": [ + "Identifies an object from its siblings within the context of its parent object. The distinguished name contains a sequence of relative names." + ], + "isConfigurable": false, + "propGlobalId": "2", + "propLocalId": "3", + "label": "rn", + "baseType": "reference:BinRN", + "modelType": "reference:BinRN", + "needsPropDelimiters": true, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "state": { + "versions": "1.0(1e)-", + "comment": [ + "Represents the state of the relationship." + ], + "isConfigurable": false, + "propGlobalId": "103", + "propLocalId": "26", + "label": "State", + "baseType": "scalar:Enum8", + "modelType": "reln:State", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "5", "localName": "cardinality-violation", + "platformFlavors": [ + + ], + "comment": [ + "cardinality violation - When relations are created such that\n they violate the cardinality, state of the relation would be\n set to this." + ], + "label": "Cardinality Violation "}, + { "value": "unformed", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "1", "localName": "formed", + "platformFlavors": [ + + ], + "comment": [ + "the relationship is formed with the target object" + ], + "label": "Formed "}, + { "value": "4", "localName": "invalid-target", + "platformFlavors": [ + + ], + "comment": [ + "invalid target DN" + ], + "label": "Invalid Target "}, + { "value": "2", "localName": "missing-target", + "platformFlavors": [ + + ], + "comment": [ + "target does not exist" + ], + "label": "Missing Target "}, + { "value": "0", "localName": "unformed", + "platformFlavors": [ + + ], + "comment": [ + "the relationship is not formed" + ], + "label": "Unformed "} + ], + "default": "unformed", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "stateQual": { + "versions": "1.0(1e)-", + "comment": [ + "Represents the state qualifier of the relationship." + ], + "isConfigurable": false, + "propGlobalId": "104", + "propLocalId": "80", + "label": "State Qualifier", + "baseType": "scalar:Enum8", + "modelType": "reln:StateQual", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "2", "localName": "default-target", + "platformFlavors": [ + + ], + "comment": [ + "target not specified, using default" + ], + "label": "Target Not Specified "}, + { "value": "none", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "1", "localName": "mismatch-target", + "platformFlavors": [ + + ], + "comment": [ + "target not found, using default" + ], + "label": "Target Not Found "}, + { "value": "0", "localName": "none", + "platformFlavors": [ + + ], + "comment": [ + "no issue" + ], + "label": "None "} + ], + "default": "none", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "status": { + "versions": "1.0(1e)-", + "comment": [ + "The upgrade status. This property is for internal use only." + ], + "isConfigurable": false, + "propGlobalId": "3", + "propLocalId": "4", + "label": "status", + "baseType": "scalar:Bitmask32", + "modelType": "mo:ModificationStatus", + "needsPropDelimiters": false, + "uitype": "bitmask", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validValues": [ + { "value": "2", "localName": "created", + "platformFlavors": [ + + ], + "comment": [ + "In a setter method: specifies that an object should be created. An error is returned if the object already exists. \nIn the return value of a setter method: indicates that an object has been created. \n" + ], + "label": "Created "}, + { "value": "8", "localName": "deleted", + "platformFlavors": [ + + ], + "comment": [ + "In a setter method: specifies that an object should be deleted. \nIn the return value of a setter method: indicates that an object has been deleted.\n" + ], + "label": "Deleted "}, + { "value": "4", "localName": "modified", + "platformFlavors": [ + + ], + "comment": [ + "In a setter method: specifies that an object should be modified \nIn the return value of a setter method: indicates that an object has been modified.\n" + ], + "label": "Modified "} + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "tCl": { + "versions": "1.0(1e)-", + "comment": [ + "The class ID of the target object. This property is managed internally and should not be modified by the user." + ], + "isConfigurable": false, + "propGlobalId": "16226", + "propLocalId": "78", + "label": "Target Class", + "baseType": "scalar:Enum16", + "modelType": "reln:ClassId", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": true, + "isLike": false, + "validValues": [ + { "value": "1482", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "1482", "localName": "pkiKeyRing", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "0", "localName": "unspecified", + "platformFlavors": [ + + ], + "label": "unspecified "} + ], + "default": "pkiKeyRing", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "tContextDn": { + "versions": "1.0(1e)-", + "comment": [ + "Specifies the target context distinguished name." + ], + "isConfigurable": false, + "propGlobalId": "4990", + "propLocalId": "2530", + "label": "Target-context", + "baseType": "reference:BinRef", + "modelType": "reln:Dn", + "needsPropDelimiters": true, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "tDn": { + "versions": "1.0(1e)-", + "comment": [ + "The distinguished name of the target." + ], + "isConfigurable": false, + "propGlobalId": "100", + "propLocalId": "77", + "label": "Target-dn", + "baseType": "reference:BinRef", + "modelType": "reln:Dn", + "needsPropDelimiters": true, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "tRn": { + "versions": "1.0(1e)-", + "comment": [ + "Specifies the target's related name." + ], + "isConfigurable": false, + "propGlobalId": "4989", + "propLocalId": "2529", + "label": "Target-rn", + "baseType": "string:Basic", + "modelType": "string:Basic", + "needsPropDelimiters": false, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "tType": { + "versions": "1.0(1e)-", + "comment": [ + "Represents the type of target. The target type for this object is named." + ], + "isConfigurable": false, + "propGlobalId": "4988", + "propLocalId": "81", + "label": "Target Type", + "baseType": "scalar:Enum8", + "modelType": "reln:TargetType", + "needsPropDelimiters": false, + "uitype": "enum", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": true, + "isLike": false, + "validValues": [ + { "value": "2", "localName": "all", + "platformFlavors": [ + + ], + "label": "All "}, + { "value": "name", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "}, + { "value": "1", "localName": "mo", + "platformFlavors": [ + + ], + "label": "MO "}, + { "value": "0", "localName": "name", + "platformFlavors": [ + + ], + "label": "Name "} + ], + "default": "name", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "tnPkiKeyRingName": { + "versions": "1.0(1e)-", + "comment": [ + "The HTTP connection key ring. Each PKI device holds a pair of asymmetric Rivest-Shamir-Adleman (RSA) or Elliptic Curve Cryptography (ECC) encryption keys, one kept private and one made public, stored in an internal key ring." + ], + "isConfigurable": true, + "propGlobalId": "16225", + "propLocalId": "3986", + "label": "Name", + "baseType": "string:Basic", + "modelType": "naming:Name", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 64, + "regexs": [ + {"regex" : "^[a-zA-Z0-9_.:-]+$", "type": "include"} + ] + } + ], + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "uid": { + "versions": "1.0(1e)-", + "comment": [ + "A unique identifier for this object." + ], + "isConfigurable": false, + "propGlobalId": "8", + "propLocalId": "8", + "label": "uid", + "baseType": "scalar:Uint16", + "modelType": "scalar:Uint16", + "needsPropDelimiters": false, + "uitype": "auto", + "createOnly": false, + "readWrite": false, + "readOnly": true, + "isNaming": false, + "secure": false, + "implicit": true, + "mandatory": false, + "isOverride": false, + "isLike": false, + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + }, + "userdom": { + "versions": "5.0(1k)-", + "isConfigurable": true, + "propGlobalId": "60657", + "propLocalId": "13244", + "label": "userdom", + "baseType": "string:Basic", + "modelType": "mo:UserDomType", + "needsPropDelimiters": false, + "uitype": "string", + "createOnly": false, + "readWrite": true, + "readOnly": false, + "isNaming": false, + "secure": false, + "implicit": false, + "mandatory": false, + "isOverride": false, + "isLike": false, + "validators": [ + {"min" : 0, "max": 1024, + "regexs": [ + {"regex" : "^[a-zA-Z0-9_.:-]+$", "type": "include"} + ] + } + ], + "validValues": [ + { "value": "all", "localName": "defaultValue", + "platformFlavors": [ + + ], + "label": " "} + ], + "default": "all", + "platformFlavors": [ + + ], + "isNxosConverged": false, + "isDeprecated": false, + "isHidden": false + } + } + } +} diff --git a/gen/templates/resource.go.tmpl b/gen/templates/resource.go.tmpl index e91b2fd43..a77c9e2c9 100644 --- a/gen/templates/resource.go.tmpl +++ b/gen/templates/resource.go.tmpl @@ -2,6 +2,68 @@ // 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). +{{- define "child_attributes" }} + "{{- .ResourceName}}": schema.SetNestedAttribute{ + MarkdownDescription: `{{.Comment}}`, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + {{- if not .IdentifiedBy}} + Validators: []validator.Set{ + setvalidator.SizeAtMost(1), + }, + {{- end}} + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + {{- range .Properties}} + {{- if eq .ValueType "bitmask"}} + "{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}": schema.SetAttribute{ + MarkdownDescription: `{{.Comment}}`, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + {{- if .ValidValues}} + Validators: []validator.Set{ + setvalidator.SizeAtMost({{ len .ValidValues }}), + setvalidator.ValueStringsAre( + stringvalidator.OneOf({{- validatorString .ValidValues}}), + ), + }, + {{- end}} + ElementType: types.StringType, + }, + {{- else}} + "{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}": schema.StringAttribute{ + {{- if or .IsNaming .IsRequired}} + Required: true, + {{- else }} + Optional: true, + Computed: true, + {{- end}} + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + {{- if .ValidValues}} + Validators: []validator.String{ + stringvalidator.OneOf({{- validatorString .ValidValues}}), + }, + {{- end}} + MarkdownDescription: `{{.Comment}}`, + }, + {{- end}} + {{- end}} + {{- range .Children}} + {{- template "child_attributes" . }} + }, + }, + }, + {{- end}} + {{- end}} + package provider import ( @@ -74,9 +136,9 @@ type {{.ResourceClassName}}ResourceModel struct { {{- end}} } -{{- range .Children}} -// {{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel describes the resource data model for the children without relation ships. -type {{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel struct { +{{ define "child_structs" }} +// {{.ResourceClassName}}{{.ParentName}}ResourceModel describes the resource data model for the children without relation ships. +type {{.ResourceClassName}}{{.ParentName}}ResourceModel struct { {{- range .Properties}} {{- if eq .ValueType "bitmask"}} {{ .Name }} types.Set `tfsdk:"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}"` @@ -86,9 +148,20 @@ type {{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel struct { {{ .Name }} types.String `tfsdk:"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}"` {{- end}} {{- end}} + {{- range .Children}} + {{ .ResourceClassName }} types.Set `tfsdk:"{{- .ResourceName}}"` + {{- end}} } +{{- range .Children}} +{{- template "child_structs" . }} +{{- end}} {{- end}} +{{- range .Children}} +{{- template "child_structs" . }} +{{- end}} + + {{if .IdentifiedBy}} type {{.ResourceClassName}}Identifier struct { {{- range .Properties}} @@ -181,64 +254,14 @@ func (r *{{.ResourceClassName}}Resource) Schema(ctx context.Context, req resourc {{- end}} {{- end}} {{- range .Children}} - "{{- .ResourceName}}": schema.SetNestedAttribute{ - MarkdownDescription: `{{.Comment}}`, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - {{- if not .IdentifiedBy}} - Validators: []validator.Set{ - setvalidator.SizeAtMost(1), - }, - {{- end}} - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - {{- range .Properties}} - {{- if eq .ValueType "bitmask"}} - "{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}": schema.SetAttribute{ - MarkdownDescription: `{{.Comment}}`, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - {{- if .ValidValues}} - Validators: []validator.Set{ - setvalidator.SizeAtMost({{ len .ValidValues }}), - setvalidator.ValueStringsAre( - stringvalidator.OneOf({{- validatorString .ValidValues}}), - ), - }, - {{- end}} - ElementType: types.StringType, - }, - {{- else}} - "{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}": schema.StringAttribute{ - {{- if or .IsNaming .IsRequired}} - Required: true, - {{- else }} - Optional: true, - Computed: true, - {{- end}} - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, - {{- if .ValidValues}} - Validators: []validator.String{ - stringvalidator.OneOf({{- validatorString .ValidValues}}), - }, - {{- end}} - MarkdownDescription: `{{.Comment}}`, - }, - {{- end}} + {{- template "child_attributes" . }} + + }, + }, + }, + {{- end}} }, - }, - }, - {{- end}} - }, } tflog.Debug(ctx, "End schema of resource: aci_{{.ResourceName}}") } @@ -290,7 +313,7 @@ func (r *{{.ResourceClassName}}Resource) Create(ctx context.Context, req resourc tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_{{.ResourceName}} with id '%s'", data.Id.ValueString())) {{ if .HasChild}} - {{- range .Children}} + {{- range .Children}} var {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel data.{{ .ResourceClassName }}.ElementsAs(ctx, &{{.PkgName}}Plan, false) stateData.{{ .ResourceClassName }}.ElementsAs(ctx, &{{.PkgName}}State, false) @@ -308,7 +331,8 @@ func (r *{{.ResourceClassName}}Resource) Create(ctx context.Context, req resourc if resp.Diagnostics.HasError() { return } - + + getAndSet{{.ResourceClassName}}Attributes(ctx, &resp.Diagnostics, r.client, data) // Save data into Terraform state @@ -361,6 +385,8 @@ func (r *{{.ResourceClassName}}Resource) Update(ctx context.Context, req resourc tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_{{.ResourceName}} with id '%s'", data.Id.ValueString())) + + {{ if .HasChild}} {{- range .Children}} var {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel @@ -377,7 +403,7 @@ func (r *{{.ResourceClassName}}Resource) Update(ctx context.Context, req resourc } DoRestRequest(ctx, &resp.Diagnostics, r.client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "POST", jsonPayload) - + if resp.Diagnostics.HasError() { return } @@ -616,6 +642,7 @@ func set{{.ResourceClassName}}Id(ctx context.Context, data *{{.ResourceClassName {{- end}} } + {{ range .Children}} func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *{{$.ResourceClassName}}ResourceModel, {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel) []map[string]interface{} { diff --git a/gen/testvars/commPol.yaml b/gen/testvars/commPol.yaml new file mode 100644 index 000000000..5258c8938 --- /dev/null +++ b/gen/testvars/commPol.yaml @@ -0,0 +1,84 @@ +# 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). + +default: + annotation: "orchestrator:terraform" + description: "" + name_alias: "" + owner_key: "" + owner_tag: "" + strict_security_on_apic_oob_subnet: "false" + +datasource_non_existing: + name: "non_existing_name" + +datasource_required: + name: "test_name" + +resource_required: + name: "test_name" + +all: + annotation: "annotation" + description: "description" + name_alias: "name_alias" + owner_key: "owner_key" + owner_tag: "owner_tag" + strict_security_on_apic_oob_subnet: "no" + +children: + http_ssl_configuration: + - access_control_allow_credential: "disabled" + access_control_allow_origins: "access_control_allow_origins_1" + admin_st: "disabled" + annotation: "annotation_1" + cli_only_mode: "disabled" + client_cert_auth_state: "disabled" + description: "description_1" + dh_param: "1024" + global_throttle_rate: "global_throttle_rate_1" + global_throttle_st: "disabled" + global_throttle_unit: "global_throttle_unit_1" + max_request_status_count: "max_request_status_count_1" + name: "name_1" + name_alias: "name_alias_1" + node_exporter: "disabled" + port: "port_1" + referer: "referer_1" + server_header: "disabled" + ssl_protocols: "TLSv1" + throttle_rate: "throttle_rate_1" + throttle_st: "disabled" + visore_access: "disabled" + + - access_control_allow_credential: "enabled" + access_control_allow_origins: "access_control_allow_origins_2" + admin_st: "enabled" + annotation: "annotation_2" + cli_only_mode: "enabled" + client_cert_auth_state: "enabled" + description: "description_2" + dh_param: "2048" + global_throttle_rate: "global_throttle_rate_2" + global_throttle_st: "enabled" + global_throttle_unit: "global_throttle_unit_2" + max_request_status_count: "max_request_status_count_2" + name: "name_2" + name_alias: "name_alias_2" + node_exporter: "enabled" + port: "port_2" + referer: "referer_2" + server_header: "enabled" + ssl_protocols: "TLSv1.1" + throttle_rate: "throttle_rate_2" + throttle_st: "enabled" + visore_access: "enabled" + + annotations: + - key: "annotations_1" + value: "value_1" + + - key: "annotations_2" + value: "value_2" + diff --git a/internal/provider/data_source_aci_communication_policy.go b/internal/provider/data_source_aci_communication_policy.go new file mode 100644 index 000000000..8c851878a --- /dev/null +++ b/internal/provider/data_source_aci_communication_policy.go @@ -0,0 +1,247 @@ +// 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). + +package provider + +import ( + "context" + "fmt" + + "github.com/ciscoecosystem/aci-go-client/v2/client" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +// Ensure provider defined types fully satisfy framework interfaces. +var _ datasource.DataSource = &CommPolDataSource{} + +func NewCommPolDataSource() datasource.DataSource { + return &CommPolDataSource{} +} + +// CommPolDataSource defines the data source implementation. +type CommPolDataSource struct { + client *client.Client +} + +func (d *CommPolDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + tflog.Debug(ctx, "Start metadata of datasource: aci_communication_policy") + resp.TypeName = req.ProviderTypeName + "_communication_policy" + tflog.Debug(ctx, "End metadata of datasource: aci_communication_policy") +} + +func (d *CommPolDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + tflog.Debug(ctx, "Start schema of datasource: aci_communication_policy") + resp.Schema = schema.Schema{ + // This description is used by the documentation generator and the language server. + MarkdownDescription: "The communication_policy datasource for the 'commPol' class", + + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The distinguished name (DN) of the Communication Policy object.", + }, + "annotation": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The annotation of the Communication Policy object.`, + }, + "description": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The description of the Communication Policy object.`, + }, + "name": schema.StringAttribute{ + Required: true, + MarkdownDescription: `The name of the Communication Policy object.`, + }, + "name_alias": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The name alias of the Communication Policy object.`, + }, + "owner_key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key for enabling clients to own their data for entity correlation.`, + }, + "owner_tag": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `A tag for enabling clients to add their own data. For example, to indicate who created this object.`, + }, + "strict_security_on_apic_oob_subnet": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `remove implicit access on apic oob from any apic OOB subnet IP.`, + }, + "http_ssl_configuration": schema.SetNestedAttribute{ + MarkdownDescription: `HTTPS`, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "access_control_allow_credential": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `accessControlAllowCredential.`, + }, + "access_control_allow_origins": schema.StringAttribute{ + Computed: true, + MarkdownDescription: ``, + }, + "admin_st": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The state of HTTPS communication service. This can be enabled or disabled.`, + }, + "annotation": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The annotation of the Http Ssl Configuration object.`, + }, + "cli_only_mode": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `CLI only mode.`, + }, + "client_cert_auth_state": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `Client Cert Auth State.`, + }, + "description": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The description of the Http Ssl Configuration object.`, + }, + "dh_param": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `DH Parameter.`, + }, + "global_throttle_rate": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The maximum MO api calls allowed per unit time.`, + }, + "global_throttle_st": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `Throttle state for all clients without tag0 in header.`, + }, + "global_throttle_unit": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `Unit of rate limit.`, + }, + "max_request_status_count": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The maximum number of request status objects to keep.`, + }, + "name": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The name of the Http Ssl Configuration object.`, + }, + "name_alias": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The name alias of the Http Ssl Configuration object.`, + }, + "node_exporter": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `Node Exporter service.`, + }, + "port": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The port used for HTTPS communication service.`, + }, + "referer": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `Allowed HTTP referer space separated list.`, + }, + "server_header": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `Server Header.`, + }, + "ssl_protocols": schema.SetAttribute{ + Computed: true, + MarkdownDescription: `The Secure Socket Layer (SSL) protocol.`, + ElementType: types.StringType, + }, + "throttle_rate": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The maximum login/refresh allowed per second.`, + }, + "throttle_st": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `Login/refresh throttle state.`, + }, + "visore_access": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `Visore Access.`, + }, + }, + }, + }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + }, + } + tflog.Debug(ctx, "End schema of datasource: aci_communication_policy") +} + +func (d *CommPolDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + tflog.Debug(ctx, "Start configure of datasource: aci_communication_policy") + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*client.Client) + + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *client.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + + return + } + + d.client = client + tflog.Debug(ctx, "End configure of datasource: aci_communication_policy") +} + +func (d *CommPolDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + tflog.Debug(ctx, "Start read of datasource: aci_communication_policy") + var data *CommPolResourceModel + + // Read Terraform configuration data into the model + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + setCommPolId(ctx, data) + + // Create a copy of the Id for when not found during getAndSetCommPolAttributes + cachedId := data.Id.ValueString() + + tflog.Debug(ctx, fmt.Sprintf("Read of datasource aci_communication_policy with id '%s'", data.Id.ValueString())) + + getAndSetCommPolAttributes(ctx, &resp.Diagnostics, d.client, data) + + if data.Id.IsNull() { + resp.Diagnostics.AddError( + "Failed to read aci_communication_policy data source", + fmt.Sprintf("The aci_communication_policy data source with id '%s' has not been found", cachedId), + ) + return + } + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) + tflog.Debug(ctx, fmt.Sprintf("End read of datasource aci_communication_policy with id '%s'", data.Id.ValueString())) +} diff --git a/internal/provider/data_source_aci_communication_policy_test.go b/internal/provider/data_source_aci_communication_policy_test.go new file mode 100644 index 000000000..fb8a6a807 --- /dev/null +++ b/internal/provider/data_source_aci_communication_policy_test.go @@ -0,0 +1,51 @@ +// 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). + +package provider + +import ( + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccDataSourceCommPol(t *testing.T) { + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testConfigCommPolDataSource, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.aci_communication_policy.test", "annotation", "annotation"), + resource.TestCheckResourceAttr("data.aci_communication_policy.test", "description", "description"), + resource.TestCheckResourceAttr("data.aci_communication_policy.test", "name_alias", "name_alias"), + resource.TestCheckResourceAttr("data.aci_communication_policy.test", "owner_key", "owner_key"), + resource.TestCheckResourceAttr("data.aci_communication_policy.test", "owner_tag", "owner_tag"), + resource.TestCheckResourceAttr("data.aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "no"), + ), + }, + { + Config: testConfigCommPolNotExisting, + ExpectError: regexp.MustCompile("Failed to read aci_communication_policy data source"), + }, + }, + }) +} + +const testConfigCommPolDataSource = testConfigCommPolAll + ` +data "aci_communication_policy" "test" { + name = "test_name" + depends_on = [aci_communication_policy.test] +} +` + +const testConfigCommPolNotExisting = testConfigCommPolAll + ` +data "aci_communication_policy" "test" { + name = "non_existing_name" + depends_on = [aci_communication_policy.test] +} +` diff --git a/internal/provider/provider.go b/internal/provider/provider.go index ddca36000..9b62c35f6 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -196,6 +196,7 @@ func (p *AciProvider) Configure(ctx context.Context, req provider.ConfigureReque func (p *AciProvider) Resources(ctx context.Context) []func() resource.Resource { return []func() resource.Resource{ + NewCommPolResource, NewFvEpIpTagResource, NewFvEpMacTagResource, NewFvFBRGroupResource, @@ -221,6 +222,7 @@ func (p *AciProvider) Resources(ctx context.Context) []func() resource.Resource func (p *AciProvider) DataSources(ctx context.Context) []func() datasource.DataSource { return []func() datasource.DataSource{ + NewCommPolDataSource, NewFvEpIpTagDataSource, NewFvEpMacTagDataSource, NewFvFBRGroupDataSource, diff --git a/internal/provider/resource_aci_communication_policy.go b/internal/provider/resource_aci_communication_policy.go new file mode 100644 index 000000000..e9b0284d8 --- /dev/null +++ b/internal/provider/resource_aci_communication_policy.go @@ -0,0 +1,1036 @@ +// 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). + +package provider + +import ( + "context" + "encoding/json" + "fmt" + "reflect" + "strings" + + "github.com/ciscoecosystem/aci-go-client/v2/client" + "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +// Ensure provider defined types fully satisfy framework interfaces. +var _ resource.Resource = &CommPolResource{} +var _ resource.ResourceWithImportState = &CommPolResource{} + +func NewCommPolResource() resource.Resource { + return &CommPolResource{} +} + +// CommPolResource defines the resource implementation. +type CommPolResource struct { + client *client.Client +} + +// CommPolResourceModel describes the resource data model. +type CommPolResourceModel struct { + Id types.String `tfsdk:"id"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + OwnerKey types.String `tfsdk:"owner_key"` + OwnerTag types.String `tfsdk:"owner_tag"` + StrictSecurityOnApicOOBSubnet types.String `tfsdk:"strict_security_on_apic_oob_subnet"` + CommHttps types.Set `tfsdk:"http_ssl_configuration"` + TagAnnotation types.Set `tfsdk:"annotations"` +} + +// CommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. +type CommHttpsCommPolResourceModel struct { + AccessControlAllowCredential types.String `tfsdk:"access_control_allow_credential"` + AccessControlAllowOrigins types.String `tfsdk:"access_control_allow_origins"` + AdminSt types.String `tfsdk:"admin_st"` + Annotation types.String `tfsdk:"annotation"` + CliOnlyMode types.String `tfsdk:"cli_only_mode"` + ClientCertAuthState types.String `tfsdk:"client_cert_auth_state"` + Descr types.String `tfsdk:"description"` + DhParam types.String `tfsdk:"dh_param"` + GlobalThrottleRate types.String `tfsdk:"global_throttle_rate"` + GlobalThrottleSt types.String `tfsdk:"global_throttle_st"` + GlobalThrottleUnit types.String `tfsdk:"global_throttle_unit"` + MaxRequestStatusCount types.String `tfsdk:"max_request_status_count"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + NodeExporter types.String `tfsdk:"node_exporter"` + Port types.String `tfsdk:"port"` + Referer types.String `tfsdk:"referer"` + ServerHeader types.String `tfsdk:"server_header"` + SslProtocols types.Set `tfsdk:"ssl_protocols"` + ThrottleRate types.String `tfsdk:"throttle_rate"` + ThrottleSt types.String `tfsdk:"throttle_st"` + VisoreAccess types.String `tfsdk:"visore_access"` + CommRsClientCertCA types.Set `tfsdk:"tp"` + CommRsKeyRing types.Set `tfsdk:"key_ring"` +} + +// CommRsClientCertCACommHttpsResourceModel describes the resource data model for the children without relation ships. +type CommRsClientCertCACommHttpsResourceModel struct { + Annotation types.String `tfsdk:"annotation"` + TDn types.String `tfsdk:"target_dn"` +} + +// CommRsKeyRingCommHttpsResourceModel describes the resource data model for the children without relation ships. +type CommRsKeyRingCommHttpsResourceModel struct { + Annotation types.String `tfsdk:"annotation"` + TnPkiKeyRingName types.String `tfsdk:"tn_pki_key_ring_name"` +} + +// TagAnnotationCommPolResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationCommPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +type CommPolIdentifier struct { + Name types.String +} + +func (r *CommPolResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + tflog.Debug(ctx, "Start metadata of resource: aci_communication_policy") + resp.TypeName = req.ProviderTypeName + "_communication_policy" + tflog.Debug(ctx, "End metadata of resource: aci_communication_policy") +} + +func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + tflog.Debug(ctx, "Start schema of resource: aci_communication_policy") + resp.Schema = schema.Schema{ + // This description is used by the documentation generator and the language server. + MarkdownDescription: "The communication_policy resource for the 'commPol' class", + + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The distinguished name (DN) of the Communication Policy object.", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "annotation": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Default: stringdefault.StaticString(globalAnnotation), + MarkdownDescription: `The annotation of the Communication Policy object.`, + }, + "description": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The description of the Communication Policy object.`, + }, + "name": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + stringplanmodifier.RequiresReplace(), + }, + MarkdownDescription: `The name of the Communication Policy object.`, + }, + "name_alias": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The name alias of the Communication Policy object.`, + }, + "owner_key": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The key for enabling clients to own their data for entity correlation.`, + }, + "owner_tag": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `A tag for enabling clients to add their own data. For example, to indicate who created this object.`, + }, + "strict_security_on_apic_oob_subnet": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("no", "yes"), + }, + MarkdownDescription: `remove implicit access on apic oob from any apic OOB subnet IP.`, + }, + "http_ssl_configuration": schema.SetNestedAttribute{ + MarkdownDescription: `HTTPS`, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.Set{ + setvalidator.SizeAtMost(1), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "access_control_allow_credential": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("disabled", "enabled"), + }, + MarkdownDescription: `accessControlAllowCredential.`, + }, + "access_control_allow_origins": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: ``, + }, + "admin_st": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("disabled", "enabled"), + }, + MarkdownDescription: `The state of HTTPS communication service. This can be enabled or disabled.`, + }, + "annotation": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The annotation of the Http Ssl Configuration object.`, + }, + "cli_only_mode": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("disabled", "enabled"), + }, + MarkdownDescription: `CLI only mode.`, + }, + "client_cert_auth_state": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("disabled", "enabled"), + }, + MarkdownDescription: `Client Cert Auth State.`, + }, + "description": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The description of the Http Ssl Configuration object.`, + }, + "dh_param": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("1024", "2048", "4096", "none"), + }, + MarkdownDescription: `DH Parameter.`, + }, + "global_throttle_rate": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The maximum MO api calls allowed per unit time.`, + }, + "global_throttle_st": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("disabled", "enabled"), + }, + MarkdownDescription: `Throttle state for all clients without tag0 in header.`, + }, + "global_throttle_unit": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `Unit of rate limit.`, + }, + "max_request_status_count": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The maximum number of request status objects to keep.`, + }, + "name": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The name of the Http Ssl Configuration object.`, + }, + "name_alias": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The name alias of the Http Ssl Configuration object.`, + }, + "node_exporter": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("disabled", "enabled"), + }, + MarkdownDescription: `Node Exporter service.`, + }, + "port": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The port used for HTTPS communication service.`, + }, + "referer": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `Allowed HTTP referer space separated list.`, + }, + "server_header": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("disabled", "enabled"), + }, + MarkdownDescription: `Server Header.`, + }, + "ssl_protocols": schema.SetAttribute{ + MarkdownDescription: `The Secure Socket Layer (SSL) protocol.`, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.Set{ + setvalidator.SizeAtMost(4), + setvalidator.ValueStringsAre( + stringvalidator.OneOf("TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"), + ), + }, + ElementType: types.StringType, + }, + "throttle_rate": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The maximum login/refresh allowed per second.`, + }, + "throttle_st": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("disabled", "enabled"), + }, + MarkdownDescription: `Login/refresh throttle state.`, + }, + "visore_access": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("disabled", "enabled"), + }, + MarkdownDescription: `Visore Access.`, + }, + "tp": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.Set{ + setvalidator.SizeAtMost(1), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "annotation": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The annotation of the Tp object.`, + }, + "target_dn": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The distinguished name of the target.`, + }, + }, + }, + }, + "key_ring": schema.SetNestedAttribute{ + MarkdownDescription: `A source relation to a key ring.`, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.Set{ + setvalidator.SizeAtMost(1), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "annotation": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The annotation of the Key Ring object.`, + }, + "tn_pki_key_ring_name": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The HTTP connection key ring. Each PKI device holds a pair of asymmetric Rivest-Shamir-Adleman (RSA) or Elliptic Curve Cryptography (ECC) encryption keys, one kept private and one made public, stored in an internal key ring.`, + }, + }, + }, + }, + }, + }, + }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + }, + } + tflog.Debug(ctx, "End schema of resource: aci_communication_policy") +} + +func (r *CommPolResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + tflog.Debug(ctx, "Start configure of resource: aci_communication_policy") + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*client.Client) + + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *client.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + + return + } + + r.client = client + tflog.Debug(ctx, "End configure of resource: aci_communication_policy") +} + +func (r *CommPolResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + tflog.Debug(ctx, "Start create of resource: aci_communication_policy") + // On create retrieve information on current state prior to making any changes in order to determine child delete operations + var stateData *CommPolResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) + setCommPolId(ctx, stateData) + getAndSetCommPolAttributes(ctx, &resp.Diagnostics, r.client, stateData) + + var data *CommPolResourceModel + + // Read Terraform plan data into the model + resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + setCommPolId(ctx, data) + + tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_communication_policy with id '%s'", data.Id.ValueString())) + + var commHttpsPlan, commHttpsState []CommHttpsCommPolResourceModel + data.CommHttps.ElementsAs(ctx, &commHttpsPlan, false) + stateData.CommHttps.ElementsAs(ctx, &commHttpsState, false) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationCommPolResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + jsonPayload := getCommPolCreateJsonPayload(ctx, &resp.Diagnostics, data, commHttpsPlan, commHttpsState, tagAnnotationPlan, tagAnnotationState) + + if resp.Diagnostics.HasError() { + return + } + + DoRestRequest(ctx, &resp.Diagnostics, r.client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "POST", jsonPayload) + if resp.Diagnostics.HasError() { + return + } + + getAndSetCommPolAttributes(ctx, &resp.Diagnostics, r.client, data) + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) + tflog.Debug(ctx, fmt.Sprintf("End create of resource aci_communication_policy with id '%s'", data.Id.ValueString())) +} + +func (r *CommPolResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + tflog.Debug(ctx, "Start read of resource: aci_communication_policy") + var data *CommPolResourceModel + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("Read of resource aci_communication_policy with id '%s'", data.Id.ValueString())) + + getAndSetCommPolAttributes(ctx, &resp.Diagnostics, r.client, data) + + // Save updated data into Terraform state + if data.Id.IsNull() { + var emptyData *CommPolResourceModel + resp.Diagnostics.Append(resp.State.Set(ctx, &emptyData)...) + } else { + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) + } + + tflog.Debug(ctx, fmt.Sprintf("End read of resource aci_communication_policy with id '%s'", data.Id.ValueString())) +} + +func (r *CommPolResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + tflog.Debug(ctx, "Start update of resource: aci_communication_policy") + var data *CommPolResourceModel + var stateData *CommPolResourceModel + + // Read Terraform plan data into the model + resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) + + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_communication_policy with id '%s'", data.Id.ValueString())) + + var commHttpsPlan, commHttpsState []CommHttpsCommPolResourceModel + data.CommHttps.ElementsAs(ctx, &commHttpsPlan, false) + stateData.CommHttps.ElementsAs(ctx, &commHttpsState, false) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationCommPolResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + jsonPayload := getCommPolCreateJsonPayload(ctx, &resp.Diagnostics, data, commHttpsPlan, commHttpsState, tagAnnotationPlan, tagAnnotationState) + + if resp.Diagnostics.HasError() { + return + } + + DoRestRequest(ctx, &resp.Diagnostics, r.client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "POST", jsonPayload) + + if resp.Diagnostics.HasError() { + return + } + + getAndSetCommPolAttributes(ctx, &resp.Diagnostics, r.client, data) + + // Save updated data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) + tflog.Debug(ctx, fmt.Sprintf("End update of resource aci_communication_policy with id '%s'", data.Id.ValueString())) +} + +func (r *CommPolResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + tflog.Debug(ctx, "Start delete of resource: aci_communication_policy") + var data *CommPolResourceModel + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, fmt.Sprintf("Delete of resource aci_communication_policy with id '%s'", data.Id.ValueString())) + jsonPayload := GetDeleteJsonPayload(ctx, &resp.Diagnostics, "commPol", data.Id.ValueString()) + if resp.Diagnostics.HasError() { + return + } + DoRestRequest(ctx, &resp.Diagnostics, r.client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "POST", jsonPayload) + if resp.Diagnostics.HasError() { + return + } + tflog.Debug(ctx, fmt.Sprintf("End delete of resource aci_communication_policy with id '%s'", data.Id.ValueString())) +} + +func (r *CommPolResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + tflog.Debug(ctx, "Start import state of resource: aci_communication_policy") + resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) + + var stateData *CommPolResourceModel + resp.Diagnostics.Append(resp.State.Get(ctx, &stateData)...) + tflog.Debug(ctx, fmt.Sprintf("Import state of resource aci_communication_policy with id '%s'", stateData.Id.ValueString())) + + tflog.Debug(ctx, "End import of state resource: aci_communication_policy") +} + +func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *CommPolResourceModel) { + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "commPol,commHttps,tagAnnotation"), "GET", nil) + + if diags.HasError() { + return + } + if requestData.Search("imdata").Search("commPol").Data() != nil { + classReadInfo := requestData.Search("imdata").Search("commPol").Data().([]interface{}) + if len(classReadInfo) == 1 { + attributes := classReadInfo[0].(map[string]interface{})["attributes"].(map[string]interface{}) + for attributeName, attributeValue := range attributes { + if attributeName == "dn" { + data.Id = basetypes.NewStringValue(attributeValue.(string)) + } + if attributeName == "annotation" { + data.Annotation = basetypes.NewStringValue(attributeValue.(string)) + } + if attributeName == "descr" { + data.Descr = basetypes.NewStringValue(attributeValue.(string)) + } + if attributeName == "name" { + data.Name = basetypes.NewStringValue(attributeValue.(string)) + } + if attributeName == "nameAlias" { + data.NameAlias = basetypes.NewStringValue(attributeValue.(string)) + } + if attributeName == "ownerKey" { + data.OwnerKey = basetypes.NewStringValue(attributeValue.(string)) + } + if attributeName == "ownerTag" { + data.OwnerTag = basetypes.NewStringValue(attributeValue.(string)) + } + if attributeName == "strictSecurityOnApicOOBSubnet" { + data.StrictSecurityOnApicOOBSubnet = basetypes.NewStringValue(attributeValue.(string)) + } + } + CommHttpsCommPolList := make([]CommHttpsCommPolResourceModel, 1) + TagAnnotationCommPolList := make([]TagAnnotationCommPolResourceModel, 0) + _, ok := classReadInfo[0].(map[string]interface{})["children"] + if ok { + children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) + for _, child := range children { + for childClassName, childClassDetails := range child.(map[string]interface{}) { + childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) + if childClassName == "commHttps" { + CommHttpsCommPol := CommHttpsCommPolResourceModel{} + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "accessControlAllowCredential" { + CommHttpsCommPol.AccessControlAllowCredential = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "accessControlAllowOrigins" { + CommHttpsCommPol.AccessControlAllowOrigins = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "adminSt" { + CommHttpsCommPol.AdminSt = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "annotation" { + CommHttpsCommPol.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "cliOnlyMode" { + CommHttpsCommPol.CliOnlyMode = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "clientCertAuthState" { + CommHttpsCommPol.ClientCertAuthState = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "descr" { + CommHttpsCommPol.Descr = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "dhParam" && childAttributeValue.(string) == "" { + CommHttpsCommPol.DhParam = basetypes.NewStringValue("none") + } else if childAttributeName == "dhParam" { + CommHttpsCommPol.DhParam = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "globalThrottleRate" { + CommHttpsCommPol.GlobalThrottleRate = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "globalThrottleSt" { + CommHttpsCommPol.GlobalThrottleSt = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "globalThrottleUnit" { + CommHttpsCommPol.GlobalThrottleUnit = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "maxRequestStatusCount" { + CommHttpsCommPol.MaxRequestStatusCount = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "name" { + CommHttpsCommPol.Name = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "nameAlias" { + CommHttpsCommPol.NameAlias = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "nodeExporter" { + CommHttpsCommPol.NodeExporter = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "port" { + CommHttpsCommPol.Port = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "referer" { + CommHttpsCommPol.Referer = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "serverHeader" { + CommHttpsCommPol.ServerHeader = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "sslProtocols" { + sslProtocolsList := strings.Split(childAttributeValue.(string), ",") + sslProtocolsSet, _ := types.SetValueFrom(ctx, CommHttpsCommPol.SslProtocols.ElementType(ctx), sslProtocolsList) + CommHttpsCommPol.SslProtocols = sslProtocolsSet + } + if childAttributeName == "throttleRate" { + CommHttpsCommPol.ThrottleRate = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "throttleSt" { + CommHttpsCommPol.ThrottleSt = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "visoreAccess" { + CommHttpsCommPol.VisoreAccess = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + CommHttpsCommPolList[0] = CommHttpsCommPol + } + if childClassName == "tagAnnotation" { + TagAnnotationCommPol := TagAnnotationCommPolResourceModel{} + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagAnnotationCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagAnnotationCommPolList = append(TagAnnotationCommPolList, TagAnnotationCommPol) + } + } + } + } + if len(CommHttpsCommPolList) > 0 { + commHttpsSet, _ := types.SetValueFrom(ctx, data.CommHttps.ElementType(ctx), CommHttpsCommPolList) + data.CommHttps = commHttpsSet + } + if len(TagAnnotationCommPolList) > 0 { + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationCommPolList) + data.TagAnnotation = tagAnnotationSet + } + } else { + diags.AddError( + "too many results in response", + fmt.Sprintf("%v matches returned for class 'commPol'. Please report this issue to the provider developers.", len(classReadInfo)), + ) + } + } else { + data.Id = basetypes.NewStringNull() + } +} + +func getCommPolRn(ctx context.Context, data *CommPolResourceModel) string { + rn := "comm-{name}" + for _, identifier := range []string{"name"} { + fieldName := fmt.Sprintf("%s%s", strings.ToUpper(identifier[:1]), identifier[1:]) + fieldValue := reflect.ValueOf(data).Elem().FieldByName(fieldName).Interface().(basetypes.StringValue).ValueString() + rn = strings.ReplaceAll(rn, fmt.Sprintf("{%s}", identifier), fieldValue) + } + return rn +} + +func setCommPolId(ctx context.Context, data *CommPolResourceModel) { + rn := getCommPolRn(ctx, data) + data.Id = types.StringValue(fmt.Sprintf("%s/%s", strings.Split([]string{"uni/fabric/comm-{name}"}[0], "/")[0], rn)) +} + +func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, commHttpsPlan, commHttpsState []CommHttpsCommPolResourceModel) []map[string]interface{} { + + childPayloads := []map[string]interface{}{} + if !data.CommHttps.IsUnknown() { + for _, commHttps := range commHttpsPlan { + childMap := map[string]map[string]interface{}{"attributes": {}} + if !commHttps.AccessControlAllowCredential.IsUnknown() { + childMap["attributes"]["accessControlAllowCredential"] = commHttps.AccessControlAllowCredential.ValueString() + } + if !commHttps.AccessControlAllowOrigins.IsUnknown() { + childMap["attributes"]["accessControlAllowOrigins"] = commHttps.AccessControlAllowOrigins.ValueString() + } + if !commHttps.AdminSt.IsUnknown() { + childMap["attributes"]["adminSt"] = commHttps.AdminSt.ValueString() + } + if !commHttps.Annotation.IsUnknown() { + childMap["attributes"]["annotation"] = commHttps.Annotation.ValueString() + } else { + childMap["attributes"]["annotation"] = globalAnnotation + } + if !commHttps.CliOnlyMode.IsUnknown() { + childMap["attributes"]["cliOnlyMode"] = commHttps.CliOnlyMode.ValueString() + } + if !commHttps.ClientCertAuthState.IsUnknown() { + childMap["attributes"]["clientCertAuthState"] = commHttps.ClientCertAuthState.ValueString() + } + if !commHttps.Descr.IsUnknown() { + childMap["attributes"]["descr"] = commHttps.Descr.ValueString() + } + if !commHttps.DhParam.IsUnknown() { + childMap["attributes"]["dhParam"] = commHttps.DhParam.ValueString() + } + if !commHttps.GlobalThrottleRate.IsUnknown() { + childMap["attributes"]["globalThrottleRate"] = commHttps.GlobalThrottleRate.ValueString() + } + if !commHttps.GlobalThrottleSt.IsUnknown() { + childMap["attributes"]["globalThrottleSt"] = commHttps.GlobalThrottleSt.ValueString() + } + if !commHttps.GlobalThrottleUnit.IsUnknown() { + childMap["attributes"]["globalThrottleUnit"] = commHttps.GlobalThrottleUnit.ValueString() + } + if !commHttps.MaxRequestStatusCount.IsUnknown() { + childMap["attributes"]["maxRequestStatusCount"] = commHttps.MaxRequestStatusCount.ValueString() + } + if !commHttps.Name.IsUnknown() { + childMap["attributes"]["name"] = commHttps.Name.ValueString() + } + if !commHttps.NameAlias.IsUnknown() { + childMap["attributes"]["nameAlias"] = commHttps.NameAlias.ValueString() + } + if !commHttps.NodeExporter.IsUnknown() { + childMap["attributes"]["nodeExporter"] = commHttps.NodeExporter.ValueString() + } + if !commHttps.Port.IsUnknown() { + childMap["attributes"]["port"] = commHttps.Port.ValueString() + } + if !commHttps.Referer.IsUnknown() { + childMap["attributes"]["referer"] = commHttps.Referer.ValueString() + } + if !commHttps.ServerHeader.IsUnknown() { + childMap["attributes"]["serverHeader"] = commHttps.ServerHeader.ValueString() + } + if !commHttps.SslProtocols.IsUnknown() { + var tmpSslProtocols []string + commHttps.SslProtocols.ElementsAs(ctx, &tmpSslProtocols, false) + childMap["attributes"]["sslProtocols"] = strings.Join(tmpSslProtocols, ",") + } + if !commHttps.ThrottleRate.IsUnknown() { + childMap["attributes"]["throttleRate"] = commHttps.ThrottleRate.ValueString() + } + if !commHttps.ThrottleSt.IsUnknown() { + childMap["attributes"]["throttleSt"] = commHttps.ThrottleSt.ValueString() + } + if !commHttps.VisoreAccess.IsUnknown() { + childMap["attributes"]["visoreAccess"] = commHttps.VisoreAccess.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"commHttps": childMap}) + } + if len(commHttpsPlan) == 0 && len(commHttpsState) == 1 { + diags.AddError( + "CommHttps object cannot be deleted", + "deletion of child is only possible upon deletion of the parent", + ) + return nil + } + } else { + data.CommHttps = types.SetNull(data.CommHttps.ElementType(ctx)) + } + + return childPayloads +} +func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationCommPolResourceModel) []map[string]interface{} { + + childPayloads := []map[string]interface{}{} + if !data.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotation := range tagAnnotationPlan { + childMap := map[string]map[string]interface{}{"attributes": {}} + if !tagAnnotation.Key.IsUnknown() { + childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + } + if !tagAnnotation.Value.IsUnknown() { + childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotation := range tagAnnotationState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotation.Key { + delete = false + break + } + } + if delete { + childMap := map[string]map[string]interface{}{"attributes": {}} + childMap["attributes"]["status"] = "deleted" + childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + } + } + } else { + data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) + } + + return childPayloads +} + +func getCommPolCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, commHttpsPlan, commHttpsState []CommHttpsCommPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationCommPolResourceModel) *container.Container { + payloadMap := map[string]interface{}{} + payloadMap["attributes"] = map[string]string{} + childPayloads := []map[string]interface{}{} + + CommHttpschildPayloads := getCommPolCommHttpsChildPayloads(ctx, diags, data, commHttpsPlan, commHttpsState) + if CommHttpschildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, CommHttpschildPayloads...) + + TagAnnotationchildPayloads := getCommPolTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) + if TagAnnotationchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + + payloadMap["children"] = childPayloads + if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { + payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() + } + if !data.Descr.IsNull() && !data.Descr.IsUnknown() { + payloadMap["attributes"].(map[string]string)["descr"] = data.Descr.ValueString() + } + if !data.Name.IsNull() && !data.Name.IsUnknown() { + payloadMap["attributes"].(map[string]string)["name"] = data.Name.ValueString() + } + if !data.NameAlias.IsNull() && !data.NameAlias.IsUnknown() { + payloadMap["attributes"].(map[string]string)["nameAlias"] = data.NameAlias.ValueString() + } + if !data.OwnerKey.IsNull() && !data.OwnerKey.IsUnknown() { + payloadMap["attributes"].(map[string]string)["ownerKey"] = data.OwnerKey.ValueString() + } + if !data.OwnerTag.IsNull() && !data.OwnerTag.IsUnknown() { + payloadMap["attributes"].(map[string]string)["ownerTag"] = data.OwnerTag.ValueString() + } + if !data.StrictSecurityOnApicOOBSubnet.IsNull() && !data.StrictSecurityOnApicOOBSubnet.IsUnknown() { + payloadMap["attributes"].(map[string]string)["strictSecurityOnApicOOBSubnet"] = data.StrictSecurityOnApicOOBSubnet.ValueString() + } + + payload, err := json.Marshal(map[string]interface{}{"commPol": payloadMap}) + if err != nil { + diags.AddError( + "Marshalling of json payload failed", + fmt.Sprintf("Err: %s. Please report this issue to the provider developers.", err), + ) + return nil + } + + jsonPayload, err := container.ParseJSON(payload) + + if err != nil { + diags.AddError( + "Construction of json payload failed", + fmt.Sprintf("Err: %s. Please report this issue to the provider developers.", err), + ) + return nil + } + return jsonPayload +} diff --git a/internal/provider/resource_aci_communication_policy_test.go b/internal/provider/resource_aci_communication_policy_test.go new file mode 100644 index 000000000..9acbce50d --- /dev/null +++ b/internal/provider/resource_aci_communication_policy_test.go @@ -0,0 +1,411 @@ +// 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). + +package provider + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccResourceCommPol(t *testing.T) { + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create with minimum config and verify default APIC values + { + Config: testConfigCommPolMin, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_communication_policy.test", "name", "test_name"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "description", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "false"), + ), + }, + // Update with all config and verify default APIC values + { + Config: testConfigCommPolAll, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_communication_policy.test", "name", "test_name"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotation", "annotation"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "description", "description"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "name_alias", "name_alias"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_key", "owner_key"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_tag", "owner_tag"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "no"), + ), + }, + // Update with minimum config and verify config is unchanged + { + Config: testConfigCommPolMin, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_communication_policy.test", "name", "test_name"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "description", "description"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "name_alias", "name_alias"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_key", "owner_key"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_tag", "owner_tag"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "no"), + ), + }, + // Update with empty strings config or default value + { + Config: testConfigCommPolReset, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_communication_policy.test", "name", "test_name"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "description", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "false"), + ), + }, + // Import testing + { + ResourceName: "aci_communication_policy.test", + ImportState: true, + ImportStateVerify: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_communication_policy.test", "name", "test_name"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "description", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "false"), + ), + }, + // Update with children + { + Config: testConfigCommPolChildren, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "description", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "false"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.key", "annotations_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.1.key", "annotations_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_credential", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.dh_param", "1024"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_rate", "global_throttle_rate_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_unit", "global_throttle_unit_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.max_request_status_count", "max_request_status_count_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name", "name_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name_alias", "name_alias_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.node_exporter", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.port", "port_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.referer", "referer_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.server_header", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.ssl_protocols", "TLSv1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.access_control_allow_credential", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.access_control_allow_origins", "access_control_allow_origins_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.admin_st", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.annotation", "annotation_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.cli_only_mode", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.client_cert_auth_state", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.description", "description_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.dh_param", "2048"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.global_throttle_rate", "global_throttle_rate_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.global_throttle_st", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.global_throttle_unit", "global_throttle_unit_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.max_request_status_count", "max_request_status_count_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.name", "name_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.name_alias", "name_alias_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.node_exporter", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.port", "port_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.referer", "referer_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.server_header", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.ssl_protocols", "TLSv1.1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.throttle_rate", "throttle_rate_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.throttle_st", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.visore_access", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "2"), + ), + }, + // Update with children removed from config + { + Config: testConfigCommPolChildrenRemoveFromConfig, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "description", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "false"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.key", "annotations_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.1.key", "annotations_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_credential", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.dh_param", "1024"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_rate", "global_throttle_rate_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_unit", "global_throttle_unit_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.max_request_status_count", "max_request_status_count_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name", "name_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name_alias", "name_alias_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.node_exporter", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.port", "port_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.referer", "referer_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.server_header", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.ssl_protocols", "TLSv1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.access_control_allow_credential", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.access_control_allow_origins", "access_control_allow_origins_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.admin_st", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.annotation", "annotation_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.cli_only_mode", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.client_cert_auth_state", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.description", "description_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.dh_param", "2048"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.global_throttle_rate", "global_throttle_rate_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.global_throttle_st", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.global_throttle_unit", "global_throttle_unit_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.max_request_status_count", "max_request_status_count_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.name", "name_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.name_alias", "name_alias_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.node_exporter", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.port", "port_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.referer", "referer_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.server_header", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.ssl_protocols", "TLSv1.1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.throttle_rate", "throttle_rate_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.throttle_st", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.visore_access", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "2"), + ), + }, + // Update with children first child removed + { + Config: testConfigCommPolChildrenRemoveOne, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "description", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "false"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.key", "annotations_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_credential", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.dh_param", "2048"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_rate", "global_throttle_rate_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_st", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_unit", "global_throttle_unit_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.max_request_status_count", "max_request_status_count_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name", "name_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name_alias", "name_alias_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.node_exporter", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.port", "port_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.referer", "referer_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.server_header", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.ssl_protocols", "TLSv1.1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "1"), + ), + }, + // Update with all children removed + { + Config: testConfigCommPolChildrenRemoveAll, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "description", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "false"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.#", "0"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "0"), + ), + }, + }, + }) +} + +const testConfigCommPolMin = ` +resource "aci_communication_policy" "test" { + name = "test_name" +} +` + +const testConfigCommPolAll = ` +resource "aci_communication_policy" "test" { + name = "test_name" + annotation = "annotation" + description = "description" + name_alias = "name_alias" + owner_key = "owner_key" + owner_tag = "owner_tag" + strict_security_on_apic_oob_subnet = "no" +} +` + +const testConfigCommPolReset = ` +resource "aci_communication_policy" "test" { + name = "test_name" + annotation = "orchestrator:terraform" + description = "" + name_alias = "" + owner_key = "" + owner_tag = "" + strict_security_on_apic_oob_subnet = "false" +} +` +const testConfigCommPolChildren = ` +resource "aci_communication_policy" "test" { + name = "test_name" + annotations = [ + { + key = "annotations_1" + value = "value_1" + }, + { + key = "annotations_2" + value = "value_2" + }, + ] + http_ssl_configuration = [ + { + access_control_allow_credential = "disabled" + access_control_allow_origins = "access_control_allow_origins_1" + admin_st = "disabled" + annotation = "annotation_1" + cli_only_mode = "disabled" + client_cert_auth_state = "disabled" + description = "description_1" + dh_param = "1024" + global_throttle_rate = "global_throttle_rate_1" + global_throttle_st = "disabled" + global_throttle_unit = "global_throttle_unit_1" + max_request_status_count = "max_request_status_count_1" + name = "name_1" + name_alias = "name_alias_1" + node_exporter = "disabled" + port = "port_1" + referer = "referer_1" + server_header = "disabled" + ssl_protocols = "TLSv1" + throttle_rate = "throttle_rate_1" + throttle_st = "disabled" + visore_access = "disabled" + }, + { + access_control_allow_credential = "enabled" + access_control_allow_origins = "access_control_allow_origins_2" + admin_st = "enabled" + annotation = "annotation_2" + cli_only_mode = "enabled" + client_cert_auth_state = "enabled" + description = "description_2" + dh_param = "2048" + global_throttle_rate = "global_throttle_rate_2" + global_throttle_st = "enabled" + global_throttle_unit = "global_throttle_unit_2" + max_request_status_count = "max_request_status_count_2" + name = "name_2" + name_alias = "name_alias_2" + node_exporter = "enabled" + port = "port_2" + referer = "referer_2" + server_header = "enabled" + ssl_protocols = "TLSv1.1" + throttle_rate = "throttle_rate_2" + throttle_st = "enabled" + visore_access = "enabled" + }, + ] +} +` + +const testConfigCommPolChildrenRemoveFromConfig = ` +resource "aci_communication_policy" "test" { + name = "test_name" +} +` + +const testConfigCommPolChildrenRemoveOne = ` +resource "aci_communication_policy" "test" { + name = "test_name" + annotations = [ + { + key = "annotations_2" + value = "value_2" + }, + ] + http_ssl_configuration = [ + { + access_control_allow_credential = "enabled" + access_control_allow_origins = "access_control_allow_origins_2" + admin_st = "enabled" + annotation = "annotation_2" + cli_only_mode = "enabled" + client_cert_auth_state = "enabled" + description = "description_2" + dh_param = "2048" + global_throttle_rate = "global_throttle_rate_2" + global_throttle_st = "enabled" + global_throttle_unit = "global_throttle_unit_2" + max_request_status_count = "max_request_status_count_2" + name = "name_2" + name_alias = "name_alias_2" + node_exporter = "enabled" + port = "port_2" + referer = "referer_2" + server_header = "enabled" + ssl_protocols = "TLSv1.1" + throttle_rate = "throttle_rate_2" + throttle_st = "enabled" + visore_access = "enabled" + }, + ] +} +` + +const testConfigCommPolChildrenRemoveAll = ` +resource "aci_communication_policy" "test" { + name = "test_name" + annotations = [] + http_ssl_configuration = [] +} +` From a65c959bc4f622979ae45d3f2cb1d070f50cfaa1 Mon Sep 17 00:00:00 2001 From: Shreyas Date: Thu, 28 Mar 2024 16:34:56 -0400 Subject: [PATCH 02/20] [ignore] Changed go template format --- gen/templates/resource.go.tmpl | 132 +++++++++--------- ...nal_management_network_instance_profile.go | 16 ++- 2 files changed, 82 insertions(+), 66 deletions(-) diff --git a/gen/templates/resource.go.tmpl b/gen/templates/resource.go.tmpl index a77c9e2c9..26e9c4c4d 100644 --- a/gen/templates/resource.go.tmpl +++ b/gen/templates/resource.go.tmpl @@ -2,67 +2,6 @@ // 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). -{{- define "child_attributes" }} - "{{- .ResourceName}}": schema.SetNestedAttribute{ - MarkdownDescription: `{{.Comment}}`, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - {{- if not .IdentifiedBy}} - Validators: []validator.Set{ - setvalidator.SizeAtMost(1), - }, - {{- end}} - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - {{- range .Properties}} - {{- if eq .ValueType "bitmask"}} - "{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}": schema.SetAttribute{ - MarkdownDescription: `{{.Comment}}`, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - {{- if .ValidValues}} - Validators: []validator.Set{ - setvalidator.SizeAtMost({{ len .ValidValues }}), - setvalidator.ValueStringsAre( - stringvalidator.OneOf({{- validatorString .ValidValues}}), - ), - }, - {{- end}} - ElementType: types.StringType, - }, - {{- else}} - "{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}": schema.StringAttribute{ - {{- if or .IsNaming .IsRequired}} - Required: true, - {{- else }} - Optional: true, - Computed: true, - {{- end}} - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, - {{- if .ValidValues}} - Validators: []validator.String{ - stringvalidator.OneOf({{- validatorString .ValidValues}}), - }, - {{- end}} - MarkdownDescription: `{{.Comment}}`, - }, - {{- end}} - {{- end}} - {{- range .Children}} - {{- template "child_attributes" . }} - }, - }, - }, - {{- end}} - {{- end}} package provider @@ -255,13 +194,12 @@ func (r *{{.ResourceClassName}}Resource) Schema(ctx context.Context, req resourc {{- end}} {{- range .Children}} {{- template "child_attributes" . }} - - }, - }, }, + }, + }, {{- end}} - }, + }, } tflog.Debug(ctx, "End schema of resource: aci_{{.ResourceName}}") } @@ -777,3 +715,67 @@ func get{{.ResourceClassName}}CreateJsonPayload(ctx context.Context, diags *diag } return jsonPayload } + +{{- define "child_attributes" }} + "{{ .ResourceName }}": schema.SetNestedAttribute{ + MarkdownDescription: `{{ .Comment }}`, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + {{- if not .IdentifiedBy }} + Validators: []validator.Set{ + setvalidator.SizeAtMost(1), + }, + {{- end }} + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + {{- range .Properties }} + {{- if eq .ValueType "bitmask" }} + "{{ overwriteProperty .PkgName .SnakeCaseName $.Definitions }}": schema.SetAttribute{ + MarkdownDescription: `{{ .Comment }}`, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + {{- if .ValidValues }} + Validators: []validator.Set{ + setvalidator.SizeAtMost({{ len .ValidValues }}), + setvalidator.ValueStringsAre( + stringvalidator.OneOf({{ validatorString .ValidValues }}), + ), + }, + {{- end }} + ElementType: types.StringType, + }, + {{- else }} + "{{ overwriteProperty .PkgName .SnakeCaseName $.Definitions }}": schema.StringAttribute{ + {{- if or .IsNaming .IsRequired }} + Required: true, + {{- else }} + Optional: true, + Computed: true, + {{- end }} + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + {{- if .ValidValues }} + Validators: []validator.String{ + stringvalidator.OneOf({{ validatorString .ValidValues }}), + }, + {{- end }} + MarkdownDescription: `{{ .Comment }}`, + }, + {{- end }} + {{- end }} + }, + {{- range .Children }} + "{{ .ResourceName }}": { + {{- template "child_attributes" . }} + }, + {{- end }} + }, + }, +{{- end }} \ No newline at end of file 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 5b4b737e2..087516598 100644 --- a/internal/provider/resource_aci_external_management_network_instance_profile.go +++ b/internal/provider/resource_aci_external_management_network_instance_profile.go @@ -439,6 +439,21 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, data.Prio = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.Descr.IsUnknown() { + data.Descr = types.StringNull() + } + if data.Name.IsUnknown() { + data.Name = types.StringNull() + } + if data.NameAlias.IsUnknown() { + data.NameAlias = types.StringNull() + } + if data.Prio.IsUnknown() { + data.Prio = types.StringNull() + } MgmtRsOoBConsMgmtInstPList := make([]MgmtRsOoBConsMgmtInstPResourceModel, 0) TagAnnotationMgmtInstPList := make([]TagAnnotationMgmtInstPResourceModel, 0) TagTagMgmtInstPList := make([]TagTagMgmtInstPResourceModel, 0) @@ -644,7 +659,6 @@ func getMgmtInstPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostic return childPayloads } - func getMgmtInstPCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, mgmtRsOoBConsPlan, mgmtRsOoBConsState []MgmtRsOoBConsMgmtInstPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtInstPResourceModel, tagTagPlan, tagTagState []TagTagMgmtInstPResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} From 7d537eba5224524db591a1a4834cce51da848988 Mon Sep 17 00:00:00 2001 From: Shreyas Date: Thu, 11 Apr 2024 13:53:48 -0400 Subject: [PATCH 03/20] [ignore] Made changes to resource template to accommodate recursion for child payloads --- docs/data-sources/communication_policy.md | 4 + docs/resources/communication_policy.md | 13 + .../resource-all-attributes.tf | 6 + gen/definitions/classes.yaml | 5 + gen/generator.go | 30 +- gen/templates/resource.go.tmpl | 374 +++++++++++--- gen/testvars/commPol.yaml | 7 + .../data_source_aci_communication_policy.go | 16 + internal/provider/resource_aci_annotation.go | 8 + .../resource_aci_communication_policy.go | 476 ++++++++++++++++-- .../resource_aci_communication_policy_test.go | 31 ++ .../provider/resource_aci_endpoint_tag_ip.go | 89 +++- .../provider/resource_aci_endpoint_tag_mac.go | 89 +++- ...nal_management_network_instance_profile.go | 111 +++- ..._aci_external_management_network_subnet.go | 85 +++- .../resource_aci_l3out_consumer_label.go | 97 +++- .../resource_aci_l3out_redistribute_policy.go | 77 ++- .../resource_aci_out_of_band_contract.go | 105 +++- .../resource_aci_pim_route_map_entry.go | 101 +++- .../resource_aci_pim_route_map_policy.go | 89 +++- ...lation_to_consumed_out_of_band_contract.go | 77 ++- internal/provider/resource_aci_tag.go | 8 + internal/provider/utils.go | 50 ++ 23 files changed, 1669 insertions(+), 279 deletions(-) diff --git a/docs/data-sources/communication_policy.md b/docs/data-sources/communication_policy.md index 6f8647135..fff9a7072 100644 --- a/docs/data-sources/communication_policy.md +++ b/docs/data-sources/communication_policy.md @@ -79,3 +79,7 @@ data "aci_communication_policy" "example" { * `annotations` - (list) A list of Annotations objects ([tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags objects ([tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/resources/communication_policy.md b/docs/resources/communication_policy.md index c9971c1a8..57be179b7 100644 --- a/docs/resources/communication_policy.md +++ b/docs/resources/communication_policy.md @@ -85,6 +85,12 @@ resource "aci_communication_policy" "full_example" { value = "value_1" } ] + tags = [ + { + key = "tags_1" + value = "value_1" + } + ] } ``` @@ -178,6 +184,13 @@ All examples for the Communication Policy resource can be found in the [examples * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. +* `tags` - (list) A list of Tags objects ([tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + ## Importing An existing Communication Policy can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/examples/resources/aci_communication_policy/resource-all-attributes.tf b/examples/resources/aci_communication_policy/resource-all-attributes.tf index 9797a184f..d8bd2997d 100644 --- a/examples/resources/aci_communication_policy/resource-all-attributes.tf +++ b/examples/resources/aci_communication_policy/resource-all-attributes.tf @@ -39,4 +39,10 @@ resource "aci_communication_policy" "full_example" { value = "value_1" } ] + tags = [ + { + key = "tags_1" + value = "value_1" + } + ] } diff --git a/gen/definitions/classes.yaml b/gen/definitions/classes.yaml index a28175ee5..c7c2deb29 100644 --- a/gen/definitions/classes.yaml +++ b/gen/definitions/classes.yaml @@ -218,3 +218,8 @@ mplsNodeSidP: - "uni/tn-{name}/out-{name}/lnodep-{name}/rsnodeL3OutAtt-[{tDn}]/lbp-[{addr}]/nodesidp-{sidoffset}" contained_by: - "l3extLoopBackIfP" + +commPol: + contained_by: + - "polUni" + rn_prepend: "fabric" diff --git a/gen/generator.go b/gen/generator.go index de5716d71..18d210c67 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -102,6 +102,7 @@ var templateFuncs = template.FuncMap{ "capitalize": Capitalize, "getTestConfigVariableName": GetTestConfigVariableName, "getDevnetDocForClass": GetDevnetDocForClass, + "lowerFirstCharacter": LowerFirstCharacter, } // Global variables used for unique resource name setting based on label from meta data @@ -226,6 +227,13 @@ func FromInterfacesToString(identifiedBy []interface{}) string { return fmt.Sprintf("\"%s\"", strings.Join(identifiers, "\", \"")) } +func LowerFirstCharacter(str string) string { + if str == "" { + return "" + } + return strings.ToLower(string(str[0])) + str[1:] +} + // Renders the templates and writes a file to the output directory func renderTemplate(templateName, outputFileName, outputPath string, outputData interface{}) { templateData, err := os.ReadFile(fmt.Sprintf("%s/%s", templatePath, templateName)) @@ -291,7 +299,7 @@ func getClassModels(definitions Definitions) map[string]Model { for _, pkgName := range pkgNames { classModel := Model{PkgName: pkgName} - classModel.setClassModel(metaPath, false, definitions, []string{}, pkgNames, nil) + classModel.setClassModel(metaPath, false, definitions, []string{}, pkgNames, nil, nil) classModels[pkgName] = classModel } return classModels @@ -638,6 +646,7 @@ type Model struct { RelationshipResourceName string Versions string ParentName string + GrandParentName string ChildClasses []string ContainedBy []string Contains []string @@ -713,7 +722,7 @@ type Definitions struct { } // Reads the class details from the meta file and sets all details to the Model -func (m *Model) setClassModel(metaPath string, isChildIteration bool, definitions Definitions, parents, pkgNames, mainParentChildren []string) { +func (m *Model) setClassModel(metaPath string, isChildIteration bool, definitions Definitions, parents, pkgNames, mainParentChildren, parentsList []string) { fileContent, err := os.ReadFile(fmt.Sprintf("%s/%s.json", metaPath, m.PkgName)) if err != nil { log.Fatal("Error when opening file: ", err) @@ -756,14 +765,17 @@ func (m *Model) setClassModel(metaPath string, isChildIteration bool, definition - Incorrect: Parent -> Child -> Grandchild // TODO add grandchild logic */ - + parentsList = append(parentsList, parents...) + if len(parents) != 0 { + m.SetGrandParentName(parentsList, parents[0]) + } if len(m.ChildClasses) > 0 { mainParentChildren := append(mainParentChildren, m.ChildClasses...) m.HasChild = true m.Children = make(map[string]Model) for _, child := range m.ChildClasses { childModel := Model{PkgName: child} - childModel.setClassModel(metaPath, true, definitions, []string{m.ResourceClassName}, pkgNames, mainParentChildren) + childModel.setClassModel(metaPath, true, definitions, []string{m.ResourceClassName}, pkgNames, mainParentChildren, parentsList) m.Children[child] = childModel if childModel.HasValidValues { m.HasValidValues = true @@ -940,6 +952,16 @@ func (m *Model) SetParentName(classPkgName []string) { m.ParentName = classPkgName[0] } +func (m *Model) SetGrandParentName(parentList []string, parent string) { + for i, value := range parentList { + if value == parent { + if i > 0 { + m.GrandParentName = parentList[i-1] + } + } + } +} + // Determine if a class is allowed to be deleted as defined in the classes.yaml file // Flag created to ensure classes that only classes allowed to be deleted are deleted func (m *Model) SetResourceNotesAndWarnigns(classPkgName string, definitions Definitions) { diff --git a/gen/templates/resource.go.tmpl b/gen/templates/resource.go.tmpl index 26e9c4c4d..85ecff606 100644 --- a/gen/templates/resource.go.tmpl +++ b/gen/templates/resource.go.tmpl @@ -75,29 +75,9 @@ type {{.ResourceClassName}}ResourceModel struct { {{- end}} } -{{ define "child_structs" }} -// {{.ResourceClassName}}{{.ParentName}}ResourceModel describes the resource data model for the children without relation ships. -type {{.ResourceClassName}}{{.ParentName}}ResourceModel struct { - {{- range .Properties}} - {{- if eq .ValueType "bitmask"}} - {{ .Name }} types.Set `tfsdk:"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}"` - {{- else if eq .Name "Id"}} - {{.ResourceClassName}}{{ .Name }} types.String `tfsdk:"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}"` - {{- else}} - {{ .Name }} types.String `tfsdk:"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}"` - {{- end}} - {{- end}} - {{- range .Children}} - {{ .ResourceClassName }} types.Set `tfsdk:"{{- .ResourceName}}"` - {{- end}} -} -{{- range .Children}} -{{- template "child_structs" . }} -{{- end}} -{{- end}} {{- range .Children}} -{{- template "child_structs" . }} +{{- template "childStructs" . }} {{- end}} @@ -155,6 +135,7 @@ func (r *{{.ResourceClassName}}Resource) Schema(ctx context.Context, req resourc Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, {{- if .ValidValues}} Validators: []validator.Set{ @@ -176,6 +157,7 @@ func (r *{{.ResourceClassName}}Resource) Schema(ctx context.Context, req resourc {{- end}} PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), {{- if or .IsNaming .CreateOnly}} stringplanmodifier.RequiresReplace(), {{- end}} @@ -193,12 +175,11 @@ func (r *{{.ResourceClassName}}Resource) Schema(ctx context.Context, req resourc {{- end}} {{- end}} {{- range .Children}} - {{- template "child_attributes" . }} - }, + {{- template "childAttributes" . }} }, - }, - - {{- end}} + }, + }, + {{- end}} }, } tflog.Debug(ctx, "End schema of resource: aci_{{.ResourceName}}") @@ -252,10 +233,10 @@ func (r *{{.ResourceClassName}}Resource) Create(ctx context.Context, req resourc {{ if .HasChild}} {{- range .Children}} - var {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel - data.{{ .ResourceClassName }}.ElementsAs(ctx, &{{.PkgName}}Plan, false) - stateData.{{ .ResourceClassName }}.ElementsAs(ctx, &{{.PkgName}}State, false) - {{- end}} + var {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{.ParentName}}ResourceModel + data.{{ .ResourceClassName }}.ElementsAs(ctx, &{{.PkgName}}Plan, false) + stateData.{{ .ResourceClassName }}.ElementsAs(ctx, &{{.PkgName}}State, false) + {{- end}} jsonPayload := get{{.ResourceClassName}}CreateJsonPayload(ctx, &resp.Diagnostics, data{{- range .Children}}, {{.PkgName}}Plan, {{.PkgName}}State{{- end}}) {{- else}} jsonPayload := get{{.ResourceClassName}}CreateJsonPayload(ctx, &resp.Diagnostics, data) @@ -403,7 +384,7 @@ func (r *{{.ResourceClassName}}Resource) ImportState(ctx context.Context, req re func getAndSet{{.ResourceClassName}}Attributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *{{.ResourceClassName}}ResourceModel) { {{- if .HasChild}} - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "{{- .PkgName}},{{- listToString .ChildClasses}}"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) {{- else}} requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) {{- end}} @@ -455,14 +436,20 @@ func getAndSet{{.ResourceClassName}}Attributes(ctx context.Context, diags *diag. {{- end}} {{- end}} } + + {{- range .Properties}} + if data.{{.Name}}.IsUnknown() { + {{- if eq .ValueType "bitmask"}} + data.{{.Name}} = types.SetNull(data.{{.Name}}.ElementType(ctx)) + {{- else}} + data.{{.Name}} = types.StringNull() + {{- end}} + } + {{- end}} {{- if .HasChild}} {{- range .Children}} - {{- if .IdentifiedBy}} - {{ .ResourceClassName }}{{$.ResourceClassName}}List := make([]{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel, 0) - {{- else}} - {{ .ResourceClassName }}{{$.ResourceClassName}}List := make([]{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel, 1) - {{- end}} + {{- template "declareChildLists" . }} {{- end}} _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -482,14 +469,22 @@ func getAndSet{{.ResourceClassName}}Attributes(ctx context.Context, diags *diag. {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}} = {{.PropertyName}}Set } else if childAttributeName == "{{.PropertyName}}" { {{.PropertyName}}List := strings.Split(childAttributeValue.(string), ",") - {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}}.ElementType(ctx), {{.PropertyName}}List) + var data{{.ResourceClassName}}{{$.ResourceClassName}} []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel + data.{{.ResourceClassName}}.ElementsAs(ctx,&data{{.ResourceClassName}}{{$.ResourceClassName}},false) + for _, {{.ResourceClassName | lowerFirstCharacter}} := range data{{.ResourceClassName}}{{$.ResourceClassName}} { + {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, {{.ResourceClassName | lowerFirstCharacter}}.{{.Name}}.ElementType(ctx),{{.PropertyName}}List) {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}} = {{.PropertyName}}Set + } } {{- else}} if childAttributeName == "{{.PropertyName}}" { {{.PropertyName}}List := strings.Split(childAttributeValue.(string), ",") - {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}}.ElementType(ctx), {{.PropertyName}}List) + var data{{.ResourceClassName}}{{$.ResourceClassName}} []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel + data.{{.ResourceClassName}}.ElementsAs(ctx,&data{{.ResourceClassName}}{{$.ResourceClassName}},false) + for _, {{.ResourceClassName | lowerFirstCharacter}} := range data{{.ResourceClassName}}{{$.ResourceClassName}} { + {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, {{.ResourceClassName | lowerFirstCharacter}}.{{.Name}}.ElementType(ctx),{{.PropertyName}}List) {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}} = {{.PropertyName}}Set + } } {{- end}} {{- else}} @@ -506,7 +501,40 @@ func getAndSet{{.ResourceClassName}}Attributes(ctx context.Context, diags *diag. {{- end}} {{- end}} {{- end}} + {{- $parentLevel := .ResourceClassName }} + {{- $parentLevelCloseBracket := .ResourceClassName }} + {{- range .Children}} + {{- if eq $parentLevel .ParentName }} + {{- $parentLevel = .ResourceClassName }} + childClasses{{.ParentName}} := childClassDetails.(map[string]interface{})["children"].([]interface{}) + for _, child{{.ParentName}} := range childClasses{{.ParentName}} { + for childClassName{{.ParentName}}, childClassDetails{{.ParentName}} := range child{{.ParentName}}.(map[string]interface{}) { + {{- end}} + if childClassName{{.ParentName}} == "{{.PkgName}}" { + {{- template "getAndSetGrandChildren" . }} + {{- if eq $parentLevelCloseBracket .ParentName }} + {{- $parentLevelCloseBracket = .ResourceClassName }} + {{- else}} + } + } + {{- end }} + {{- end }} + } + {{- range .Properties}} + if {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}}.IsUnknown() { + {{- if eq .ValueType "bitmask"}} + var data{{.PropertyName}}{{.ResourceClassName}}{{$.ResourceClassName}} []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel + data.{{.ResourceClassName}}.ElementsAs(ctx,&data{{.PropertyName}}{{.ResourceClassName}}{{$.ResourceClassName}},false) + for _, {{.ResourceClassName | lowerFirstCharacter}} := range data{{.PropertyName}}{{.ResourceClassName}}{{$.ResourceClassName}} { + if {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}}.IsUnknown(){ + {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}} = types.SetNull({{.ResourceClassName | lowerFirstCharacter}}.{{.Name}}.ElementType(ctx)) + } + } + {{- else}} + {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}} = types.StringNull() + {{- end}} } + {{- end}} {{- if .IdentifiedBy}} {{.ResourceClassName}}{{$.ResourceClassName}}List = append({{.ResourceClassName}}{{$.ResourceClassName}}List, {{.ResourceClassName}}{{$.ResourceClassName}}) {{- else}} @@ -583,31 +611,47 @@ func set{{.ResourceClassName}}Id(ctx context.Context, data *{{.ResourceClassName {{ range .Children}} func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *{{$.ResourceClassName}}ResourceModel, {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel) []map[string]interface{} { - - childPayloads := []map[string]interface{}{} - if !data.{{ .ResourceClassName }}.IsUnknown() { - {{- if .IdentifiedBy}} - {{ .PkgName }}Identifiers := []{{ .ResourceClassName }}Identifier{} - {{- end}} - for _, {{ .PkgName }} := range {{ .PkgName }}Plan { - childMap := map[string]map[string]interface{}{"attributes": {}} - {{- range .Properties}} - if !{{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsUnknown(){ - {{- if eq .ValueType "bitmask"}} - var tmp{{ .Name }} []string - {{ .PkgName }}.{{ .Name }}.ElementsAs(ctx, &tmp{{ .Name }}, false) - childMap["attributes"]["{{ .PropertyName }}"] = strings.Join(tmp{{ .Name }}, ",") - {{- else if eq .Name "Id"}} - childMap["attributes"]["{{ .PropertyName }}"] = {{ .PkgName }}.{{.ResourceClassName}}{{ .Name }}.ValueString() - {{- else}} - childMap["attributes"]["{{ .PropertyName }}"] = {{ .PkgName }}.{{ .Name }}.ValueString() +type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } +childPayloads := []map[string]interface{}{} +if !data.{{.ResourceClassName}}.IsUnknown() { + {{- if .IdentifiedBy}} + {{ .PkgName }}Identifiers := []{{.ResourceClassName}}Identifier{} + {{- end}} + for _, {{ .PkgName }} := range {{ .PkgName }}Plan { + {{- range .Properties}} + if !{{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsUnknown(){ + {{- if eq .ValueType "bitmask"}} + var tmp{{ .Name }} []string + {{ .PkgName }}.{{ .Name }}.ElementsAs(ctx, &tmp{{ .Name }}, false) + childMap.Attributes["{{ .PropertyName }}"] = strings.Join(tmp{{ .Name }}, ",") + {{- else if eq .Name "Id"}} + childMap.Attributes["{{ .PropertyName }}"] = {{ .PkgName }}.{{.ResourceClassName}}{{ .Name }}.ValueString() + {{- else}} + childMap.Attributes["{{ .PropertyName }}"] = {{ .PkgName }}.{{ .Name }}.ValueString() + {{- end}} + } {{- if eq .Name "Annotation" }} else { + childMap.Attributes["annotation"] = globalAnnotation + } {{- end}} {{- end}} - } {{- if eq .Name "Annotation" }} else { - childMap["attributes"]["annotation"] = globalAnnotation - } {{- end}} - {{- end}} - childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": childMap}) - {{- if .IdentifiedBy}} + {{- $parentLevel := .ParentName }} + {{- range .Children}} + {{- if ne $parentLevel .ParentName }} + {{- $parentLevel = .ParentName }} + {{.ParentName}}Children := make([]map[string]interface{}, 0) + {{- end}} + {{- template "grandChildPayloads" . }} + } + childMap.Children = {{ .ParentName }}Children + {{- end}} +childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": childMap}) +{{- if .IdentifiedBy}} {{ .PkgName }}Identifier := {{ .ResourceClassName }}Identifier{} {{- range .Properties}} {{- if .IsNaming}} @@ -632,11 +676,13 @@ func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" {{- range .Properties}} {{- if .IsNaming }} - childMap["attributes"]["{{.PropertyName}}"] = {{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.ValueString() + childMap.Attributes["{{.PropertyName}}"] = {{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.ValueString() {{- end}} {{- end}} childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": childMap}) @@ -645,8 +691,10 @@ func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context {{- else}} if len({{ .PkgName }}Plan) == 0 && len({{ .PkgName }}State) == 1 { {{- if .AllowDelete}} - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": childMap}) {{- else}} diags.AddError( @@ -663,7 +711,7 @@ func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context return childPayloads } -{{- end}} +{{ end}} func get{{.ResourceClassName}}CreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *{{.ResourceClassName}}ResourceModel{{- range .Children}}, {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel{{- end}}) *container.Container { payloadMap := map[string]interface{}{} @@ -716,13 +764,37 @@ func get{{.ResourceClassName}}CreateJsonPayload(ctx context.Context, diags *diag return jsonPayload } -{{- define "child_attributes" }} - "{{ .ResourceName }}": schema.SetNestedAttribute{ +{{/* A sub template for the child structs used in the structs definiton section. */}} +{{- define "childStructs" }} +// {{.ResourceClassName}}{{.ParentName}}ResourceModel describes the resource data model for the children without relation ships. +type {{.ResourceClassName}}{{.ParentName}}ResourceModel struct { + {{- range .Properties}} + {{- if eq .ValueType "bitmask"}} + {{ .Name }} types.Set `tfsdk:"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}"` + {{- else if eq .Name "Id"}} + {{.ResourceClassName}}{{ .Name }} types.String `tfsdk:"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}"` + {{- else}} + {{ .Name }} types.String `tfsdk:"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}"` + {{- end}} + {{- end}} + {{- range .Children}} + {{ .ResourceClassName }} types.Set `tfsdk:"{{- .ResourceName}}"` + {{- end}} +} +{{- range .Children}} +{{- template "childStructs" . }} +{{- end}} +{{- end}} + +{{/* A sub template for the child attributes used in the Attributes block. */}} +{{- define "childAttributes" }} + "{{- .ResourceName }}": schema.SetNestedAttribute{ MarkdownDescription: `{{ .Comment }}`, Optional: true, Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, {{- if not .IdentifiedBy }} Validators: []validator.Set{ @@ -739,12 +811,13 @@ func get{{.ResourceClassName}}CreateJsonPayload(ctx context.Context, diags *diag Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, {{- if .ValidValues }} Validators: []validator.Set{ setvalidator.SizeAtMost({{ len .ValidValues }}), setvalidator.ValueStringsAre( - stringvalidator.OneOf({{ validatorString .ValidValues }}), + stringvalidator.OneOf({{- validatorString .ValidValues }}), ), }, {{- end }} @@ -760,22 +833,169 @@ func get{{.ResourceClassName}}CreateJsonPayload(ctx context.Context, diags *diag {{- end }} PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, {{- if .ValidValues }} Validators: []validator.String{ - stringvalidator.OneOf({{ validatorString .ValidValues }}), + stringvalidator.OneOf({{- validatorString .ValidValues }}), }, {{- end }} MarkdownDescription: `{{ .Comment }}`, }, {{- end }} {{- end }} - }, {{- range .Children }} - "{{ .ResourceName }}": { - {{- template "child_attributes" . }} + {{- template "childAttributes" . }} }, - {{- end }} }, }, -{{- end }} \ No newline at end of file + {{- end }} +{{- end }} + +{{/* A sub template for the grand child attributes used in the Payload function. */}} +{{- define "grandChildPayloads" }} +var {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{.ParentName}}ResourceModel +for i, {{.ParentName | lowerFirstCharacter}} := range {{.ParentName | lowerFirstCharacter}}Plan { +{{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}Plan, false) +{{ .ParentName | lowerFirstCharacter}}Plan[i].{{.ResourceClassName}},_ = types.SetValueFrom(ctx,{{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementType(ctx),{{.PkgName}}Plan) +} +for i, {{.ParentName | lowerFirstCharacter}} := range {{.ParentName | lowerFirstCharacter}}State { + {{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}State, false) + {{ .ParentName | lowerFirstCharacter}}State[i].{{.ResourceClassName}},_ = types.SetValueFrom(ctx,{{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementType(ctx),{{.PkgName}}State) +} +if len({{ .PkgName }}Plan) == 0 && len({{ .PkgName }}State) == 1 { + {{- if .AllowDelete}} + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": childMap}) + {{- else}} + diags.AddError( + "{{ .ResourceClassName }} object cannot be deleted", + "deletion of child is only possible upon deletion of the parent", + ) + return nil + {{- end }} +} +if !{{ .ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.IsUnknown(){ + for _, {{ .PkgName }} := range {{.PkgName}}Plan { + {{.PkgName}}ChildMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } + {{- range .Properties}} + if !{{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsUnknown(){ + {{- if eq .ValueType "bitmask"}} + var tmp{{ .Name }} []string + {{ .PkgName }}.{{ .Name }}.ElementsAs(ctx, &tmp{{ .Name }}, false) + {{.PkgName}}ChildMap.Attributes["{{ .PropertyName }}"] = strings.Join(tmp{{ .Name }}, ",") + {{- else if eq .Name "Id"}} + {{.PkgName}}ChildMap.Attributes["{{ .PropertyName }}"] = {{ .PkgName }}.{{.ResourceClassName}}{{ .Name }}.ValueString() + {{- else}} + {{.PkgName}}ChildMap.Attributes["{{ .PropertyName }}"] = {{ .PkgName }}.{{ .Name }}.ValueString() + {{- end}} + } {{- if eq .Name "Annotation" }} else { + {{.PkgName}}ChildMap.Attributes["annotation"] = globalAnnotation + } {{- end}} + {{- end}} + {{- $parentLevel := .ParentName }} + {{- range .Children}} + {{- if ne $parentLevel .ParentName }} + {{- $parentLevel = .ParentName }} + {{.ParentName}}Children := make([]map[string]interface{}, 0) + {{- end}} + {{- template "grandChildPayloads" . }} + {{- end}} + {{ .ParentName }}Children = append({{ .ParentName }}Children, map[string]interface{}{"{{.PkgName}}": {{.PkgName}}ChildMap}) + } +{{- end }} + + + +{{- define "declareChildLists" }} +{{- if .IdentifiedBy}} +{{ .ResourceClassName }}{{$.ParentName}}List := make([]{{.ResourceClassName}}{{$.ParentName}}ResourceModel, 0) +{{- else}} +{{ .ResourceClassName }}{{$.ParentName}}List := make([]{{.ResourceClassName}}{{$.ParentName}}ResourceModel, 1) +{{- end}} +{{- range .Children}} +{{- template "declareChildLists" . }} +{{- end}} +{{- end}} + + +{{- define "getAndSetGrandChildren" }} +{{.ResourceClassName}}{{.ParentName}} := {{ .ResourceClassName}}{{.ParentName}}ResourceModel{} +{{.PkgName}}childAttributeValue:= childClassDetails{{.ParentName}}.(map[string]interface{})["attributes"].(map[string]interface{}) +for childAttributeName, childAttributeValue := range {{.PkgName}}childAttributeValue { + {{- range .Properties}} + {{- if eq .ValueType "bitmask"}} + {{- if containsNoneAttributeValue .ValidValues}} + if childAttributeName == "{{.PropertyName}}" && childAttributeValue.(string) == "" { + {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, {{.ResourceClassName}}{{$.ParentName}}.{{.Name}}.ElementType(ctx), []string{"none"}) + {{.ResourceClassName}}{{$.ParentName}}.{{.Name}} = {{.PropertyName}}Set + } else if childAttributeName == "{{.PropertyName}}" { + {{.PropertyName}}List := strings.Split(childAttributeValue.(string), ",") + var data{{.ParentName}}{{.GrandParentName}} []{{.ParentName}}{{.GrandParentName}}ResourceModel + data.{{.ParentName}}.ElementsAs(ctx,&data{{.ParentName}}{{.GrandParentName}},false) + for _, {{.ParentName | lowerFirstCharacter}} := range data{{.ResourceClassName}}{{.ParentName}} { + {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, {{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementType(ctx),{{.PropertyName}}List) + {{.ResourceClassName}}{{$.ParentName}}.{{.Name}} = {{.PropertyName}}Set + } + } + {{- else}} + if childAttributeName == "{{.PropertyName}}" { + {{.PropertyName}}List := strings.Split(childAttributeValue.(string), ",") + var data{{.ParentName}}{{.GrandParentName}} []{{.ParentName}}{{.GrandParentName}}ResourceModel + data.{{.ParentName}}.ElementsAs(ctx,&data{{.ParentName}}{{.GrandParentName}},false) + for _, {{.ParentName | lowerFirstCharacter}} := range data{{.ResourceClassName}}{{.ParentName}} { + {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, {{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementType(ctx),{{.PropertyName}}List) + {{.ResourceClassName}}{{$.ParentName}}.{{.Name}} = {{.PropertyName}}Set + } + } + {{- end}} + {{- else}} + {{- if containsNoneAttributeValue .ValidValues}} + if childAttributeName == "{{.PropertyName}}" && childAttributeValue.(string) == "" { + {{.ResourceClassName}}{{.ParentName}}.{{.Name}} = basetypes.NewStringValue("none") + } else if childAttributeName == "{{.PropertyName}}" { + {{.ResourceClassName}}{{$.ParentName}}.{{.Name}} = basetypes.NewStringValue(childAttributeValue.(string)) + } + {{- else}} + if childAttributeName == "{{.PropertyName}}" { + {{.ResourceClassName}}{{$.ParentName}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}} = basetypes.NewStringValue(childAttributeValue.(string)) + } + {{- end}} + {{- end}} + {{- end}} + {{- $parentLevel := .ParentName }} + {{- range .Children}} + {{- if ne $parentLevel .ParentName }} + {{- $parentLevel = .ParentName }} + childClasses{{.ParentName}} := childClassDetails.(map[string]interface{})["children"].(map[string]interface{}) + for _, child{{.ParentName}} := range childClasses{{.ParentName}} { + for childClassName{{.ParentName}}, childClassDetails{{.ParentName}} := range child{{.ParentName}}.([]interface{}) { + {{- end}} + if childClassName{{.ParentName}} == "{{.PkgName}}" { + {{- template "getAndSetGrandChildren" . }} + } + {{- end}} + } + {{- if .IdentifiedBy}} + {{.ResourceClassName}}{{$.ParentName}}List = append({{.ResourceClassName}}{{$.ParentName}}List, {{.ResourceClassName}}{{$.ParentName}}) + {{- else}} + {{.ResourceClassName}}{{$.ParentName}}List[0] = {{.ResourceClassName}}{{$.ParentName}} + {{- end}} + {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}},_ = types.SetValueFrom(ctx, {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}}.ElementType(ctx), {{.ResourceClassName}}{{$.ParentName}}List) + } + var data{{.ResourceClassName}}{{.ParentName}}{{.GrandParentName}} []{{.ParentName}}{{.GrandParentName}}ResourceModel + data.{{.ParentName}}.ElementsAs(ctx,&data{{.ResourceClassName}}{{.ParentName}}{{.GrandParentName}},false) + for _, {{.ParentName | lowerFirstCharacter}} := range data{{.ResourceClassName}}{{.ParentName}}{{.GrandParentName}} { + {{.ResourceClassName}}Set, _ := types.SetValueFrom(ctx, {{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementType(ctx),{{.ResourceClassName}}{{.ParentName}}List) + {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}} = {{.ResourceClassName}}Set + if {{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.IsUnknown(){ + {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}} = types.SetNull({{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementType(ctx)) + } + } +{{- end }} diff --git a/gen/testvars/commPol.yaml b/gen/testvars/commPol.yaml index 5258c8938..f9175d055 100644 --- a/gen/testvars/commPol.yaml +++ b/gen/testvars/commPol.yaml @@ -82,3 +82,10 @@ children: - key: "annotations_2" value: "value_2" + tags: + - key: "tags_1" + value: "value_1" + + - key: "tags_2" + value: "value_2" + diff --git a/internal/provider/data_source_aci_communication_policy.go b/internal/provider/data_source_aci_communication_policy.go index 8c851878a..e30e7cee5 100644 --- a/internal/provider/data_source_aci_communication_policy.go +++ b/internal/provider/data_source_aci_communication_policy.go @@ -186,6 +186,22 @@ func (d *CommPolDataSource) Schema(ctx context.Context, req datasource.SchemaReq }, }, }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of datasource: aci_communication_policy") diff --git a/internal/provider/resource_aci_annotation.go b/internal/provider/resource_aci_annotation.go index 72b1f1605..4f4116b7a 100644 --- a/internal/provider/resource_aci_annotation.go +++ b/internal/provider/resource_aci_annotation.go @@ -81,6 +81,7 @@ func (r *TagAnnotationResource) Schema(ctx context.Context, req resource.SchemaR Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, @@ -89,6 +90,7 @@ func (r *TagAnnotationResource) Schema(ctx context.Context, req resource.SchemaR Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -267,6 +269,12 @@ func getAndSetTagAnnotationAttributes(ctx context.Context, diags *diag.Diagnosti data.Value = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Key.IsUnknown() { + data.Key = types.StringNull() + } + if data.Value.IsUnknown() { + data.Value = types.StringNull() + } } else { diags.AddError( "too many results in response", diff --git a/internal/provider/resource_aci_communication_policy.go b/internal/provider/resource_aci_communication_policy.go index e9b0284d8..ee08464c6 100644 --- a/internal/provider/resource_aci_communication_policy.go +++ b/internal/provider/resource_aci_communication_policy.go @@ -54,6 +54,7 @@ type CommPolResourceModel struct { StrictSecurityOnApicOOBSubnet types.String `tfsdk:"strict_security_on_apic_oob_subnet"` CommHttps types.Set `tfsdk:"http_ssl_configuration"` TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` } // CommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. @@ -102,6 +103,12 @@ type TagAnnotationCommPolResourceModel struct { Value types.String `tfsdk:"value"` } +// TagTagCommPolResourceModel describes the resource data model for the children without relation ships. +type TagTagCommPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + type CommPolIdentifier struct { Name types.String } @@ -131,6 +138,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the Communication Policy object.`, @@ -140,6 +148,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The description of the Communication Policy object.`, }, @@ -147,6 +156,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The name of the Communication Policy object.`, @@ -156,6 +166,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the Communication Policy object.`, }, @@ -164,6 +175,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key for enabling clients to own their data for entity correlation.`, }, @@ -172,6 +184,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `A tag for enabling clients to add their own data. For example, to indicate who created this object.`, }, @@ -180,6 +193,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("no", "yes"), @@ -192,6 +206,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.Set{ setvalidator.SizeAtMost(1), @@ -203,6 +218,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("disabled", "enabled"), @@ -214,6 +230,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: ``, }, @@ -222,6 +239,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("disabled", "enabled"), @@ -233,6 +251,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The annotation of the Http Ssl Configuration object.`, }, @@ -241,6 +260,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("disabled", "enabled"), @@ -252,6 +272,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("disabled", "enabled"), @@ -263,6 +284,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The description of the Http Ssl Configuration object.`, }, @@ -271,6 +293,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("1024", "2048", "4096", "none"), @@ -282,6 +305,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The maximum MO api calls allowed per unit time.`, }, @@ -290,6 +314,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("disabled", "enabled"), @@ -301,6 +326,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `Unit of rate limit.`, }, @@ -309,6 +335,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The maximum number of request status objects to keep.`, }, @@ -317,6 +344,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name of the Http Ssl Configuration object.`, }, @@ -325,6 +353,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the Http Ssl Configuration object.`, }, @@ -333,6 +362,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("disabled", "enabled"), @@ -344,6 +374,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The port used for HTTPS communication service.`, }, @@ -352,6 +383,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `Allowed HTTP referer space separated list.`, }, @@ -360,6 +392,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("disabled", "enabled"), @@ -372,6 +405,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.Set{ setvalidator.SizeAtMost(4), @@ -386,6 +420,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The maximum login/refresh allowed per second.`, }, @@ -394,6 +429,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("disabled", "enabled"), @@ -405,6 +441,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("disabled", "enabled"), @@ -417,6 +454,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + //SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.Set{ setvalidator.SizeAtMost(1), @@ -428,6 +466,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The annotation of the Tp object.`, }, @@ -436,6 +475,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The distinguished name of the target.`, }, @@ -448,6 +488,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.Set{ setvalidator.SizeAtMost(1), @@ -459,6 +500,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The annotation of the Key Ring object.`, }, @@ -467,6 +509,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The HTTP connection key ring. Each PKI device holds a pair of asymmetric Rivest-Shamir-Adleman (RSA) or Elliptic Curve Cryptography (ECC) encryption keys, one kept private and one made public, stored in an internal key ring.`, }, @@ -482,6 +525,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -489,6 +533,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -496,6 +541,36 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -556,7 +631,10 @@ func (r *CommPolResource) Create(ctx context.Context, req resource.CreateRequest var tagAnnotationPlan, tagAnnotationState []TagAnnotationCommPolResourceModel data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - jsonPayload := getCommPolCreateJsonPayload(ctx, &resp.Diagnostics, data, commHttpsPlan, commHttpsState, tagAnnotationPlan, tagAnnotationState) + var tagTagPlan, tagTagState []TagTagCommPolResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getCommPolCreateJsonPayload(ctx, &resp.Diagnostics, data, commHttpsPlan, commHttpsState, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -621,7 +699,10 @@ func (r *CommPolResource) Update(ctx context.Context, req resource.UpdateRequest var tagAnnotationPlan, tagAnnotationState []TagAnnotationCommPolResourceModel data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - jsonPayload := getCommPolCreateJsonPayload(ctx, &resp.Diagnostics, data, commHttpsPlan, commHttpsState, tagAnnotationPlan, tagAnnotationState) + var tagTagPlan, tagTagState []TagTagCommPolResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getCommPolCreateJsonPayload(ctx, &resp.Diagnostics, data, commHttpsPlan, commHttpsState, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -675,7 +756,7 @@ func (r *CommPolResource) ImportState(ctx context.Context, req resource.ImportSt } func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *CommPolResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "commPol,commHttps,tagAnnotation"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -710,8 +791,32 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl data.StrictSecurityOnApicOOBSubnet = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.Descr.IsUnknown() { + data.Descr = types.StringNull() + } + if data.Name.IsUnknown() { + data.Name = types.StringNull() + } + if data.NameAlias.IsUnknown() { + data.NameAlias = types.StringNull() + } + if data.OwnerKey.IsUnknown() { + data.OwnerKey = types.StringNull() + } + if data.OwnerTag.IsUnknown() { + data.OwnerTag = types.StringNull() + } + if data.StrictSecurityOnApicOOBSubnet.IsUnknown() { + data.StrictSecurityOnApicOOBSubnet = types.StringNull() + } CommHttpsCommPolList := make([]CommHttpsCommPolResourceModel, 1) + CommRsClientCertCACommHttpsList := make([]CommRsClientCertCACommHttpsResourceModel, 1) + CommRsKeyRingCommHttpsList := make([]CommRsKeyRingCommHttpsResourceModel, 1) TagAnnotationCommPolList := make([]TagAnnotationCommPolResourceModel, 0) + TagTagCommPolList := make([]TagTagCommPolResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) @@ -779,8 +884,12 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl } if childAttributeName == "sslProtocols" { sslProtocolsList := strings.Split(childAttributeValue.(string), ",") - sslProtocolsSet, _ := types.SetValueFrom(ctx, CommHttpsCommPol.SslProtocols.ElementType(ctx), sslProtocolsList) - CommHttpsCommPol.SslProtocols = sslProtocolsSet + var dataCommHttpsCommPol []CommHttpsCommPolResourceModel + data.CommHttps.ElementsAs(ctx, &dataCommHttpsCommPol, false) + for _, commHttps := range dataCommHttpsCommPol { + sslProtocolsSet, _ := types.SetValueFrom(ctx, commHttps.SslProtocols.ElementType(ctx), sslProtocolsList) + CommHttpsCommPol.SslProtocols = sslProtocolsSet + } } if childAttributeName == "throttleRate" { CommHttpsCommPol.ThrottleRate = basetypes.NewStringValue(childAttributeValue.(string)) @@ -791,6 +900,129 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl if childAttributeName == "visoreAccess" { CommHttpsCommPol.VisoreAccess = basetypes.NewStringValue(childAttributeValue.(string)) } + childClassesCommHttps := childClassDetails.(map[string]interface{})["children"].([]interface{}) + for _, childCommHttps := range childClassesCommHttps { + for childClassNameCommHttps, childClassDetailsCommHttps := range childCommHttps.(map[string]interface{}) { + if childClassNameCommHttps == "commRsClientCertCA" { + CommRsClientCertCACommHttps := CommRsClientCertCACommHttpsResourceModel{} + commRsClientCertCAchildAttributeValue := childClassDetailsCommHttps.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range commRsClientCertCAchildAttributeValue { + if childAttributeName == "annotation" { + CommRsClientCertCACommHttps.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "tDn" { + CommRsClientCertCACommHttps.TDn = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + CommRsClientCertCACommHttpsList[0] = CommRsClientCertCACommHttps + CommHttpsCommPol.CommRsClientCertCA, _ = types.SetValueFrom(ctx, CommHttpsCommPol.CommRsClientCertCA.ElementType(ctx), CommRsClientCertCACommHttpsList) + } + var dataCommRsClientCertCACommHttpsCommPol []CommHttpsCommPolResourceModel + data.CommHttps.ElementsAs(ctx, &dataCommRsClientCertCACommHttpsCommPol, false) + for _, commHttps := range dataCommRsClientCertCACommHttpsCommPol { + CommRsClientCertCASet, _ := types.SetValueFrom(ctx, commHttps.CommRsClientCertCA.ElementType(ctx), CommRsClientCertCACommHttpsList) + CommHttpsCommPol.CommRsClientCertCA = CommRsClientCertCASet + if commHttps.CommRsClientCertCA.IsUnknown() { + CommHttpsCommPol.CommRsClientCertCA = types.SetNull(commHttps.CommRsClientCertCA.ElementType(ctx)) + } + } + if childClassNameCommHttps == "commRsKeyRing" { + CommRsKeyRingCommHttps := CommRsKeyRingCommHttpsResourceModel{} + commRsKeyRingchildAttributeValue := childClassDetailsCommHttps.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range commRsKeyRingchildAttributeValue { + if childAttributeName == "annotation" { + CommRsKeyRingCommHttps.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "tnPkiKeyRingName" { + CommRsKeyRingCommHttps.TnPkiKeyRingName = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + CommRsKeyRingCommHttpsList[0] = CommRsKeyRingCommHttps + CommHttpsCommPol.CommRsKeyRing, _ = types.SetValueFrom(ctx, CommHttpsCommPol.CommRsKeyRing.ElementType(ctx), CommRsKeyRingCommHttpsList) + } + var dataCommRsKeyRingCommHttpsCommPol []CommHttpsCommPolResourceModel + data.CommHttps.ElementsAs(ctx, &dataCommRsKeyRingCommHttpsCommPol, false) + for _, commHttps := range dataCommRsKeyRingCommHttpsCommPol { + CommRsKeyRingSet, _ := types.SetValueFrom(ctx, commHttps.CommRsKeyRing.ElementType(ctx), CommRsKeyRingCommHttpsList) + CommHttpsCommPol.CommRsKeyRing = CommRsKeyRingSet + if commHttps.CommRsKeyRing.IsUnknown() { + CommHttpsCommPol.CommRsKeyRing = types.SetNull(commHttps.CommRsKeyRing.ElementType(ctx)) + } + } + } + } + } + if CommHttpsCommPol.AccessControlAllowCredential.IsUnknown() { + CommHttpsCommPol.AccessControlAllowCredential = types.StringNull() + } + if CommHttpsCommPol.AccessControlAllowOrigins.IsUnknown() { + CommHttpsCommPol.AccessControlAllowOrigins = types.StringNull() + } + if CommHttpsCommPol.AdminSt.IsUnknown() { + CommHttpsCommPol.AdminSt = types.StringNull() + } + if CommHttpsCommPol.Annotation.IsUnknown() { + CommHttpsCommPol.Annotation = types.StringNull() + } + if CommHttpsCommPol.CliOnlyMode.IsUnknown() { + CommHttpsCommPol.CliOnlyMode = types.StringNull() + } + if CommHttpsCommPol.ClientCertAuthState.IsUnknown() { + CommHttpsCommPol.ClientCertAuthState = types.StringNull() + } + if CommHttpsCommPol.Descr.IsUnknown() { + CommHttpsCommPol.Descr = types.StringNull() + } + if CommHttpsCommPol.DhParam.IsUnknown() { + CommHttpsCommPol.DhParam = types.StringNull() + } + if CommHttpsCommPol.GlobalThrottleRate.IsUnknown() { + CommHttpsCommPol.GlobalThrottleRate = types.StringNull() + } + if CommHttpsCommPol.GlobalThrottleSt.IsUnknown() { + CommHttpsCommPol.GlobalThrottleSt = types.StringNull() + } + if CommHttpsCommPol.GlobalThrottleUnit.IsUnknown() { + CommHttpsCommPol.GlobalThrottleUnit = types.StringNull() + } + if CommHttpsCommPol.MaxRequestStatusCount.IsUnknown() { + CommHttpsCommPol.MaxRequestStatusCount = types.StringNull() + } + if CommHttpsCommPol.Name.IsUnknown() { + CommHttpsCommPol.Name = types.StringNull() + } + if CommHttpsCommPol.NameAlias.IsUnknown() { + CommHttpsCommPol.NameAlias = types.StringNull() + } + if CommHttpsCommPol.NodeExporter.IsUnknown() { + CommHttpsCommPol.NodeExporter = types.StringNull() + } + if CommHttpsCommPol.Port.IsUnknown() { + CommHttpsCommPol.Port = types.StringNull() + } + if CommHttpsCommPol.Referer.IsUnknown() { + CommHttpsCommPol.Referer = types.StringNull() + } + if CommHttpsCommPol.ServerHeader.IsUnknown() { + CommHttpsCommPol.ServerHeader = types.StringNull() + } + if CommHttpsCommPol.SslProtocols.IsUnknown() { + var datasslProtocolsCommHttpsCommPol []CommHttpsCommPolResourceModel + data.CommHttps.ElementsAs(ctx, &datasslProtocolsCommHttpsCommPol, false) + for _, commHttps := range datasslProtocolsCommHttpsCommPol { + if CommHttpsCommPol.SslProtocols.IsUnknown() { + CommHttpsCommPol.SslProtocols = types.SetNull(commHttps.SslProtocols.ElementType(ctx)) + } + } + } + if CommHttpsCommPol.ThrottleRate.IsUnknown() { + CommHttpsCommPol.ThrottleRate = types.StringNull() + } + if CommHttpsCommPol.ThrottleSt.IsUnknown() { + CommHttpsCommPol.ThrottleSt = types.StringNull() + } + if CommHttpsCommPol.VisoreAccess.IsUnknown() { + CommHttpsCommPol.VisoreAccess = types.StringNull() } CommHttpsCommPolList[0] = CommHttpsCommPol } @@ -804,8 +1036,32 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl TagAnnotationCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagAnnotationCommPol.Key.IsUnknown() { + TagAnnotationCommPol.Key = types.StringNull() + } + if TagAnnotationCommPol.Value.IsUnknown() { + TagAnnotationCommPol.Value = types.StringNull() + } TagAnnotationCommPolList = append(TagAnnotationCommPolList, TagAnnotationCommPol) } + if childClassName == "tagTag" { + TagTagCommPol := TagTagCommPolResourceModel{} + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagTagCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + if TagTagCommPol.Key.IsUnknown() { + TagTagCommPol.Key = types.StringNull() + } + if TagTagCommPol.Value.IsUnknown() { + TagTagCommPol.Value = types.StringNull() + } + TagTagCommPolList = append(TagTagCommPolList, TagTagCommPol) + } } } } @@ -817,6 +1073,10 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationCommPolList) data.TagAnnotation = tagAnnotationSet } + if len(TagTagCommPolList) > 0 { + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagCommPolList) + data.TagTag = tagTagSet + } } else { diags.AddError( "too many results in response", @@ -829,7 +1089,7 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl } func getCommPolRn(ctx context.Context, data *CommPolResourceModel) string { - rn := "comm-{name}" + rn := "fabric/comm-{name}" for _, identifier := range []string{"name"} { fieldName := fmt.Sprintf("%s%s", strings.ToUpper(identifier[:1]), identifier[1:]) fieldValue := reflect.ValueOf(data).Elem().FieldByName(fieldName).Interface().(basetypes.StringValue).ValueString() @@ -844,81 +1104,156 @@ func setCommPolId(ctx context.Context, data *CommPolResourceModel) { } func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, commHttpsPlan, commHttpsState []CommHttpsCommPolResourceModel) []map[string]interface{} { - + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.CommHttps.IsUnknown() { for _, commHttps := range commHttpsPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !commHttps.AccessControlAllowCredential.IsUnknown() { - childMap["attributes"]["accessControlAllowCredential"] = commHttps.AccessControlAllowCredential.ValueString() + childMap.Attributes["accessControlAllowCredential"] = commHttps.AccessControlAllowCredential.ValueString() } if !commHttps.AccessControlAllowOrigins.IsUnknown() { - childMap["attributes"]["accessControlAllowOrigins"] = commHttps.AccessControlAllowOrigins.ValueString() + childMap.Attributes["accessControlAllowOrigins"] = commHttps.AccessControlAllowOrigins.ValueString() } if !commHttps.AdminSt.IsUnknown() { - childMap["attributes"]["adminSt"] = commHttps.AdminSt.ValueString() + childMap.Attributes["adminSt"] = commHttps.AdminSt.ValueString() } if !commHttps.Annotation.IsUnknown() { - childMap["attributes"]["annotation"] = commHttps.Annotation.ValueString() + childMap.Attributes["annotation"] = commHttps.Annotation.ValueString() } else { - childMap["attributes"]["annotation"] = globalAnnotation + childMap.Attributes["annotation"] = globalAnnotation } if !commHttps.CliOnlyMode.IsUnknown() { - childMap["attributes"]["cliOnlyMode"] = commHttps.CliOnlyMode.ValueString() + childMap.Attributes["cliOnlyMode"] = commHttps.CliOnlyMode.ValueString() } if !commHttps.ClientCertAuthState.IsUnknown() { - childMap["attributes"]["clientCertAuthState"] = commHttps.ClientCertAuthState.ValueString() + childMap.Attributes["clientCertAuthState"] = commHttps.ClientCertAuthState.ValueString() } if !commHttps.Descr.IsUnknown() { - childMap["attributes"]["descr"] = commHttps.Descr.ValueString() + childMap.Attributes["descr"] = commHttps.Descr.ValueString() } if !commHttps.DhParam.IsUnknown() { - childMap["attributes"]["dhParam"] = commHttps.DhParam.ValueString() + childMap.Attributes["dhParam"] = commHttps.DhParam.ValueString() } if !commHttps.GlobalThrottleRate.IsUnknown() { - childMap["attributes"]["globalThrottleRate"] = commHttps.GlobalThrottleRate.ValueString() + childMap.Attributes["globalThrottleRate"] = commHttps.GlobalThrottleRate.ValueString() } if !commHttps.GlobalThrottleSt.IsUnknown() { - childMap["attributes"]["globalThrottleSt"] = commHttps.GlobalThrottleSt.ValueString() + childMap.Attributes["globalThrottleSt"] = commHttps.GlobalThrottleSt.ValueString() } if !commHttps.GlobalThrottleUnit.IsUnknown() { - childMap["attributes"]["globalThrottleUnit"] = commHttps.GlobalThrottleUnit.ValueString() + childMap.Attributes["globalThrottleUnit"] = commHttps.GlobalThrottleUnit.ValueString() } if !commHttps.MaxRequestStatusCount.IsUnknown() { - childMap["attributes"]["maxRequestStatusCount"] = commHttps.MaxRequestStatusCount.ValueString() + childMap.Attributes["maxRequestStatusCount"] = commHttps.MaxRequestStatusCount.ValueString() } if !commHttps.Name.IsUnknown() { - childMap["attributes"]["name"] = commHttps.Name.ValueString() + childMap.Attributes["name"] = commHttps.Name.ValueString() } if !commHttps.NameAlias.IsUnknown() { - childMap["attributes"]["nameAlias"] = commHttps.NameAlias.ValueString() + childMap.Attributes["nameAlias"] = commHttps.NameAlias.ValueString() } if !commHttps.NodeExporter.IsUnknown() { - childMap["attributes"]["nodeExporter"] = commHttps.NodeExporter.ValueString() + childMap.Attributes["nodeExporter"] = commHttps.NodeExporter.ValueString() } if !commHttps.Port.IsUnknown() { - childMap["attributes"]["port"] = commHttps.Port.ValueString() + childMap.Attributes["port"] = commHttps.Port.ValueString() } if !commHttps.Referer.IsUnknown() { - childMap["attributes"]["referer"] = commHttps.Referer.ValueString() + childMap.Attributes["referer"] = commHttps.Referer.ValueString() } if !commHttps.ServerHeader.IsUnknown() { - childMap["attributes"]["serverHeader"] = commHttps.ServerHeader.ValueString() + childMap.Attributes["serverHeader"] = commHttps.ServerHeader.ValueString() } if !commHttps.SslProtocols.IsUnknown() { var tmpSslProtocols []string commHttps.SslProtocols.ElementsAs(ctx, &tmpSslProtocols, false) - childMap["attributes"]["sslProtocols"] = strings.Join(tmpSslProtocols, ",") + childMap.Attributes["sslProtocols"] = strings.Join(tmpSslProtocols, ",") } if !commHttps.ThrottleRate.IsUnknown() { - childMap["attributes"]["throttleRate"] = commHttps.ThrottleRate.ValueString() + childMap.Attributes["throttleRate"] = commHttps.ThrottleRate.ValueString() } if !commHttps.ThrottleSt.IsUnknown() { - childMap["attributes"]["throttleSt"] = commHttps.ThrottleSt.ValueString() + childMap.Attributes["throttleSt"] = commHttps.ThrottleSt.ValueString() } if !commHttps.VisoreAccess.IsUnknown() { - childMap["attributes"]["visoreAccess"] = commHttps.VisoreAccess.ValueString() + childMap.Attributes["visoreAccess"] = commHttps.VisoreAccess.ValueString() + } + CommHttpsChildren := make([]map[string]interface{}, 0) + var commRsClientCertCAPlan, commRsClientCertCAState []CommRsClientCertCACommHttpsResourceModel + for i, commHttps := range commHttpsPlan { + commHttps.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCAPlan, false) + commHttpsPlan[i].CommRsClientCertCA, _ = types.SetValueFrom(ctx, commHttps.CommRsClientCertCA.ElementType(ctx), commRsClientCertCAPlan) + } + for i, commHttps := range commHttpsState { + commHttps.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCAState, false) + commHttpsState[i].CommRsClientCertCA, _ = types.SetValueFrom(ctx, commHttps.CommRsClientCertCA.ElementType(ctx), commRsClientCertCAState) + } + if len(commRsClientCertCAPlan) == 0 && len(commRsClientCertCAState) == 1 { + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childPayloads = append(childPayloads, map[string]interface{}{"commRsClientCertCA": childMap}) + } + if !commHttps.CommRsClientCertCA.IsUnknown() { + for _, commRsClientCertCA := range commRsClientCertCAPlan { + commRsClientCertCAChildMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } + if !commRsClientCertCA.Annotation.IsUnknown() { + commRsClientCertCAChildMap.Attributes["annotation"] = commRsClientCertCA.Annotation.ValueString() + } else { + commRsClientCertCAChildMap.Attributes["annotation"] = globalAnnotation + } + if !commRsClientCertCA.TDn.IsUnknown() { + commRsClientCertCAChildMap.Attributes["tDn"] = commRsClientCertCA.TDn.ValueString() + } + CommHttpsChildren = append(CommHttpsChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCAChildMap}) + } + } + childMap.Children = CommHttpsChildren + var commRsKeyRingPlan, commRsKeyRingState []CommRsKeyRingCommHttpsResourceModel + for i, commHttps := range commHttpsPlan { + commHttps.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingPlan, false) + commHttpsPlan[i].CommRsKeyRing, _ = types.SetValueFrom(ctx, commHttps.CommRsKeyRing.ElementType(ctx), commRsKeyRingPlan) + } + for i, commHttps := range commHttpsState { + commHttps.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingState, false) + commHttpsState[i].CommRsKeyRing, _ = types.SetValueFrom(ctx, commHttps.CommRsKeyRing.ElementType(ctx), commRsKeyRingState) + } + if len(commRsKeyRingPlan) == 0 && len(commRsKeyRingState) == 1 { + diags.AddError( + "CommRsKeyRing object cannot be deleted", + "deletion of child is only possible upon deletion of the parent", + ) + return nil + } + if !commHttps.CommRsKeyRing.IsUnknown() { + for _, commRsKeyRing := range commRsKeyRingPlan { + commRsKeyRingChildMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } + if !commRsKeyRing.Annotation.IsUnknown() { + commRsKeyRingChildMap.Attributes["annotation"] = commRsKeyRing.Annotation.ValueString() + } else { + commRsKeyRingChildMap.Attributes["annotation"] = globalAnnotation + } + if !commRsKeyRing.TnPkiKeyRingName.IsUnknown() { + commRsKeyRingChildMap.Attributes["tnPkiKeyRingName"] = commRsKeyRing.TnPkiKeyRingName.ValueString() + } + CommHttpsChildren = append(CommHttpsChildren, map[string]interface{}{"commRsKeyRing": commRsKeyRingChildMap}) + } } + childMap.Children = CommHttpsChildren childPayloads = append(childPayloads, map[string]interface{}{"commHttps": childMap}) } if len(commHttpsPlan) == 0 && len(commHttpsState) == 1 { @@ -934,18 +1269,25 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti return childPayloads } -func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationCommPolResourceModel) []map[string]interface{} { +func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationCommPolResourceModel) []map[string]interface{} { + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} @@ -961,9 +1303,11 @@ func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagn } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) } } @@ -974,7 +1318,55 @@ func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagn return childPayloads } -func getCommPolCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, commHttpsPlan, commHttpsState []CommHttpsCommPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationCommPolResourceModel) *container.Container { +func getCommPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, tagTagPlan, tagTagState []TagTagCommPolResourceModel) []map[string]interface{} { + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } + childPayloads := []map[string]interface{}{} + if !data.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTag := range tagTagPlan { + if !tagTag.Key.IsUnknown() { + childMap.Attributes["key"] = tagTag.Key.ValueString() + } + if !tagTag.Value.IsUnknown() { + childMap.Attributes["value"] = tagTag.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTag.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTag := range tagTagState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTag.Key { + delete = false + break + } + } + if delete { + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + } + } + } else { + data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) + } + + return childPayloads +} + +func getCommPolCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, commHttpsPlan, commHttpsState []CommHttpsCommPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationCommPolResourceModel, tagTagPlan, tagTagState []TagTagCommPolResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} childPayloads := []map[string]interface{}{} @@ -991,6 +1383,12 @@ func getCommPolCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, d } childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + TagTagchildPayloads := getCommPolTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) + if TagTagchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagTagchildPayloads...) + payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() diff --git a/internal/provider/resource_aci_communication_policy_test.go b/internal/provider/resource_aci_communication_policy_test.go index 9acbce50d..31b73fedd 100644 --- a/internal/provider/resource_aci_communication_policy_test.go +++ b/internal/provider/resource_aci_communication_policy_test.go @@ -143,6 +143,11 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.throttle_st", "enabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.visore_access", "enabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "tags_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.1.key", "tags_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.#", "2"), ), }, // Update with children removed from config @@ -205,6 +210,11 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.throttle_st", "enabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.visore_access", "enabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "tags_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.1.key", "tags_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.#", "2"), ), }, // Update with children first child removed @@ -243,6 +253,9 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "enabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "enabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "tags_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.#", "1"), ), }, // Update with all children removed @@ -257,6 +270,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "false"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.#", "0"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "0"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.#", "0"), ), }, }, @@ -355,6 +369,16 @@ resource "aci_communication_policy" "test" { visore_access = "enabled" }, ] + tags = [ + { + key = "tags_1" + value = "value_1" + }, + { + key = "tags_2" + value = "value_2" + }, + ] } ` @@ -399,6 +423,12 @@ resource "aci_communication_policy" "test" { visore_access = "enabled" }, ] + tags = [ + { + key = "tags_2" + value = "value_2" + }, + ] } ` @@ -407,5 +437,6 @@ resource "aci_communication_policy" "test" { name = "test_name" annotations = [] http_ssl_configuration = [] + tags = [] } ` diff --git a/internal/provider/resource_aci_endpoint_tag_ip.go b/internal/provider/resource_aci_endpoint_tag_ip.go index 2e711138e..5aed24f26 100644 --- a/internal/provider/resource_aci_endpoint_tag_ip.go +++ b/internal/provider/resource_aci_endpoint_tag_ip.go @@ -103,6 +103,7 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the Endpoint Tag Ip object.`, @@ -111,6 +112,7 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The VRF name of the Endpoint Tag Ip object.`, @@ -120,6 +122,7 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The identifier of the Endpoint Tag Ip object.`, }, @@ -127,6 +130,7 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The IP address of the Endpoint Tag Ip object.`, @@ -136,6 +140,7 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name of the Endpoint Tag Ip object.`, }, @@ -144,6 +149,7 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the Endpoint Tag Ip object.`, }, @@ -153,6 +159,7 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -160,6 +167,7 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -167,6 +175,7 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -179,6 +188,7 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -186,6 +196,7 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -193,6 +204,7 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -372,7 +384,7 @@ func (r *FvEpIpTagResource) ImportState(ctx context.Context, req resource.Import } func getAndSetFvEpIpTagAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *FvEpIpTagResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "fvEpIpTag,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -405,6 +417,24 @@ func getAndSetFvEpIpTagAttributes(ctx context.Context, diags *diag.Diagnostics, data.NameAlias = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.CtxName.IsUnknown() { + data.CtxName = types.StringNull() + } + if data.Id.IsUnknown() { + data.Id = types.StringNull() + } + if data.Ip.IsUnknown() { + data.Ip = types.StringNull() + } + if data.Name.IsUnknown() { + data.Name = types.StringNull() + } + if data.NameAlias.IsUnknown() { + data.NameAlias = types.StringNull() + } TagAnnotationFvEpIpTagList := make([]TagAnnotationFvEpIpTagResourceModel, 0) TagTagFvEpIpTagList := make([]TagTagFvEpIpTagResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] @@ -423,6 +453,12 @@ func getAndSetFvEpIpTagAttributes(ctx context.Context, diags *diag.Diagnostics, TagAnnotationFvEpIpTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagAnnotationFvEpIpTag.Key.IsUnknown() { + TagAnnotationFvEpIpTag.Key = types.StringNull() + } + if TagAnnotationFvEpIpTag.Value.IsUnknown() { + TagAnnotationFvEpIpTag.Value = types.StringNull() + } TagAnnotationFvEpIpTagList = append(TagAnnotationFvEpIpTagList, TagAnnotationFvEpIpTag) } if childClassName == "tagTag" { @@ -435,6 +471,12 @@ func getAndSetFvEpIpTagAttributes(ctx context.Context, diags *diag.Diagnostics, TagTagFvEpIpTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagTagFvEpIpTag.Key.IsUnknown() { + TagTagFvEpIpTag.Key = types.StringNull() + } + if TagTagFvEpIpTag.Value.IsUnknown() { + TagTagFvEpIpTag.Value = types.StringNull() + } TagTagFvEpIpTagList = append(TagTagFvEpIpTagList, TagTagFvEpIpTag) } } @@ -489,17 +531,23 @@ func setFvEpIpTagId(ctx context.Context, data *FvEpIpTagResourceModel) { } func getFvEpIpTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpIpTagResourceModel) []map[string]interface{} { - + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} @@ -515,9 +563,11 @@ func getFvEpIpTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) } } @@ -527,18 +577,25 @@ func getFvEpIpTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia return childPayloads } -func getFvEpIpTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagTagPlan, tagTagState []TagTagFvEpIpTagResourceModel) []map[string]interface{} { +func getFvEpIpTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagTagPlan, tagTagState []TagTagFvEpIpTagResourceModel) []map[string]interface{} { + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap.Attributes["key"] = tagTag.Key.ValueString() } if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} @@ -554,9 +611,11 @@ func getFvEpIpTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostic } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) } } diff --git a/internal/provider/resource_aci_endpoint_tag_mac.go b/internal/provider/resource_aci_endpoint_tag_mac.go index a405e067d..db1dfdb5a 100644 --- a/internal/provider/resource_aci_endpoint_tag_mac.go +++ b/internal/provider/resource_aci_endpoint_tag_mac.go @@ -103,6 +103,7 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the Endpoint Tag Mac object.`, @@ -111,6 +112,7 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The bridge domain name of the Endpoint Tag Mac object.`, @@ -120,6 +122,7 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The identifier of the Endpoint Tag Mac object.`, }, @@ -127,6 +130,7 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The MAC address of the Endpoint Tag Mac object.`, @@ -136,6 +140,7 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name of the Endpoint Tag Mac object.`, }, @@ -144,6 +149,7 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the Endpoint Tag Mac object.`, }, @@ -153,6 +159,7 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -160,6 +167,7 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -167,6 +175,7 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -179,6 +188,7 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -186,6 +196,7 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -193,6 +204,7 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -372,7 +384,7 @@ func (r *FvEpMacTagResource) ImportState(ctx context.Context, req resource.Impor } func getAndSetFvEpMacTagAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *FvEpMacTagResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "fvEpMacTag,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -405,6 +417,24 @@ func getAndSetFvEpMacTagAttributes(ctx context.Context, diags *diag.Diagnostics, data.NameAlias = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.BdName.IsUnknown() { + data.BdName = types.StringNull() + } + if data.Id.IsUnknown() { + data.Id = types.StringNull() + } + if data.Mac.IsUnknown() { + data.Mac = types.StringNull() + } + if data.Name.IsUnknown() { + data.Name = types.StringNull() + } + if data.NameAlias.IsUnknown() { + data.NameAlias = types.StringNull() + } TagAnnotationFvEpMacTagList := make([]TagAnnotationFvEpMacTagResourceModel, 0) TagTagFvEpMacTagList := make([]TagTagFvEpMacTagResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] @@ -423,6 +453,12 @@ func getAndSetFvEpMacTagAttributes(ctx context.Context, diags *diag.Diagnostics, TagAnnotationFvEpMacTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagAnnotationFvEpMacTag.Key.IsUnknown() { + TagAnnotationFvEpMacTag.Key = types.StringNull() + } + if TagAnnotationFvEpMacTag.Value.IsUnknown() { + TagAnnotationFvEpMacTag.Value = types.StringNull() + } TagAnnotationFvEpMacTagList = append(TagAnnotationFvEpMacTagList, TagAnnotationFvEpMacTag) } if childClassName == "tagTag" { @@ -435,6 +471,12 @@ func getAndSetFvEpMacTagAttributes(ctx context.Context, diags *diag.Diagnostics, TagTagFvEpMacTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagTagFvEpMacTag.Key.IsUnknown() { + TagTagFvEpMacTag.Key = types.StringNull() + } + if TagTagFvEpMacTag.Value.IsUnknown() { + TagTagFvEpMacTag.Value = types.StringNull() + } TagTagFvEpMacTagList = append(TagTagFvEpMacTagList, TagTagFvEpMacTag) } } @@ -489,17 +531,23 @@ func setFvEpMacTagId(ctx context.Context, data *FvEpMacTagResourceModel) { } func getFvEpMacTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpMacTagResourceModel) []map[string]interface{} { - + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} @@ -515,9 +563,11 @@ func getFvEpMacTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) } } @@ -527,18 +577,25 @@ func getFvEpMacTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di return childPayloads } -func getFvEpMacTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagTagPlan, tagTagState []TagTagFvEpMacTagResourceModel) []map[string]interface{} { +func getFvEpMacTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagTagPlan, tagTagState []TagTagFvEpMacTagResourceModel) []map[string]interface{} { + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap.Attributes["key"] = tagTag.Key.ValueString() } if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} @@ -554,9 +611,11 @@ func getFvEpMacTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnosti } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) } } 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 087516598..29153bd08 100644 --- a/internal/provider/resource_aci_external_management_network_instance_profile.go +++ b/internal/provider/resource_aci_external_management_network_instance_profile.go @@ -102,6 +102,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the External Management Network Instance Profile object.`, @@ -111,6 +112,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The description of the External Management Network Instance Profile object.`, }, @@ -118,6 +120,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The name of the External Management Network Instance Profile object.`, @@ -127,6 +130,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the External Management Network Instance Profile object.`, }, @@ -135,6 +139,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("level1", "level2", "level3", "level4", "level5", "level6", "unspecified"), @@ -147,6 +152,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -155,6 +161,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The annotation of the Relation To Consumed Out Of Band Contract object.`, }, @@ -163,6 +170,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("level1", "level2", "level3", "level4", "level5", "level6", "unspecified"), @@ -173,6 +181,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name of the Out Of Band Contract object.`, }, @@ -185,6 +194,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -192,6 +202,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -199,6 +210,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -211,6 +223,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -218,6 +231,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -225,6 +239,7 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -410,7 +425,7 @@ func (r *MgmtInstPResource) ImportState(ctx context.Context, req resource.Import } func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *MgmtInstPResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtInstP,mgmtRsOoBCons,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -476,6 +491,15 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, MgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName = basetypes.NewStringValue(childAttributeValue.(string)) } } + if MgmtRsOoBConsMgmtInstP.Annotation.IsUnknown() { + MgmtRsOoBConsMgmtInstP.Annotation = types.StringNull() + } + if MgmtRsOoBConsMgmtInstP.Prio.IsUnknown() { + MgmtRsOoBConsMgmtInstP.Prio = types.StringNull() + } + if MgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName.IsUnknown() { + MgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName = types.StringNull() + } MgmtRsOoBConsMgmtInstPList = append(MgmtRsOoBConsMgmtInstPList, MgmtRsOoBConsMgmtInstP) } if childClassName == "tagAnnotation" { @@ -488,6 +512,12 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, TagAnnotationMgmtInstP.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagAnnotationMgmtInstP.Key.IsUnknown() { + TagAnnotationMgmtInstP.Key = types.StringNull() + } + if TagAnnotationMgmtInstP.Value.IsUnknown() { + TagAnnotationMgmtInstP.Value = types.StringNull() + } TagAnnotationMgmtInstPList = append(TagAnnotationMgmtInstPList, TagAnnotationMgmtInstP) } if childClassName == "tagTag" { @@ -500,6 +530,12 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, TagTagMgmtInstP.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagTagMgmtInstP.Key.IsUnknown() { + TagTagMgmtInstP.Key = types.StringNull() + } + if TagTagMgmtInstP.Value.IsUnknown() { + TagTagMgmtInstP.Value = types.StringNull() + } TagTagMgmtInstPList = append(TagTagMgmtInstPList, TagTagMgmtInstP) } } @@ -538,22 +574,28 @@ func setMgmtInstPId(ctx context.Context, data *MgmtInstPResourceModel) { } func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, mgmtRsOoBConsPlan, mgmtRsOoBConsState []MgmtRsOoBConsMgmtInstPResourceModel) []map[string]interface{} { - + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.MgmtRsOoBCons.IsUnknown() { mgmtRsOoBConsIdentifiers := []MgmtRsOoBConsIdentifier{} for _, mgmtRsOoBCons := range mgmtRsOoBConsPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !mgmtRsOoBCons.Annotation.IsUnknown() { - childMap["attributes"]["annotation"] = mgmtRsOoBCons.Annotation.ValueString() + childMap.Attributes["annotation"] = mgmtRsOoBCons.Annotation.ValueString() } else { - childMap["attributes"]["annotation"] = globalAnnotation + childMap.Attributes["annotation"] = globalAnnotation } if !mgmtRsOoBCons.Prio.IsUnknown() { - childMap["attributes"]["prio"] = mgmtRsOoBCons.Prio.ValueString() + childMap.Attributes["prio"] = mgmtRsOoBCons.Prio.ValueString() } if !mgmtRsOoBCons.TnVzOOBBrCPName.IsUnknown() { - childMap["attributes"]["tnVzOOBBrCPName"] = mgmtRsOoBCons.TnVzOOBBrCPName.ValueString() + childMap.Attributes["tnVzOOBBrCPName"] = mgmtRsOoBCons.TnVzOOBBrCPName.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"mgmtRsOoBCons": childMap}) mgmtRsOoBConsIdentifier := MgmtRsOoBConsIdentifier{} @@ -569,9 +611,11 @@ func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["tnVzOOBBrCPName"] = mgmtRsOoBCons.TnVzOOBBrCPName.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["tnVzOOBBrCPName"] = mgmtRsOoBCons.TnVzOOBBrCPName.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"mgmtRsOoBCons": childMap}) } } @@ -581,18 +625,25 @@ func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Dia return childPayloads } -func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtInstPResourceModel) []map[string]interface{} { +func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtInstPResourceModel) []map[string]interface{} { + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} @@ -608,9 +659,11 @@ func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) } } @@ -620,18 +673,25 @@ func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia return childPayloads } -func getMgmtInstPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagTagPlan, tagTagState []TagTagMgmtInstPResourceModel) []map[string]interface{} { +func getMgmtInstPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagTagPlan, tagTagState []TagTagMgmtInstPResourceModel) []map[string]interface{} { + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap.Attributes["key"] = tagTag.Key.ValueString() } if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} @@ -647,9 +707,11 @@ func getMgmtInstPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostic } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) } } @@ -659,6 +721,7 @@ func getMgmtInstPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostic return childPayloads } + func getMgmtInstPCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, mgmtRsOoBConsPlan, mgmtRsOoBConsState []MgmtRsOoBConsMgmtInstPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtInstPResourceModel, tagTagPlan, tagTagState []TagTagMgmtInstPResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} diff --git a/internal/provider/resource_aci_external_management_network_subnet.go b/internal/provider/resource_aci_external_management_network_subnet.go index 846fbe0de..5b0e62612 100644 --- a/internal/provider/resource_aci_external_management_network_subnet.go +++ b/internal/provider/resource_aci_external_management_network_subnet.go @@ -101,6 +101,7 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the External Management Network Subnet object.`, @@ -110,6 +111,7 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The description of the External Management Network Subnet object.`, }, @@ -117,6 +119,7 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The external subnet IP address and subnet mask. This IP address is used for creating an external management entity. The subnet mask for the IP address to be imported from the outside into the fabric. The contracts associated with its parent instance profile (l3ext:InstP) are applied to the subnet.`, @@ -126,6 +129,7 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name of the External Management Network Subnet object.`, }, @@ -134,6 +138,7 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the External Management Network Subnet object.`, }, @@ -143,6 +148,7 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -150,6 +156,7 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -157,6 +164,7 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -169,6 +177,7 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -176,6 +185,7 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -183,6 +193,7 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -362,7 +373,7 @@ func (r *MgmtSubnetResource) ImportState(ctx context.Context, req resource.Impor } func getAndSetMgmtSubnetAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *MgmtSubnetResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtSubnet,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -392,6 +403,21 @@ func getAndSetMgmtSubnetAttributes(ctx context.Context, diags *diag.Diagnostics, data.NameAlias = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.Descr.IsUnknown() { + data.Descr = types.StringNull() + } + if data.Ip.IsUnknown() { + data.Ip = types.StringNull() + } + if data.Name.IsUnknown() { + data.Name = types.StringNull() + } + if data.NameAlias.IsUnknown() { + data.NameAlias = types.StringNull() + } TagAnnotationMgmtSubnetList := make([]TagAnnotationMgmtSubnetResourceModel, 0) TagTagMgmtSubnetList := make([]TagTagMgmtSubnetResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] @@ -410,6 +436,12 @@ func getAndSetMgmtSubnetAttributes(ctx context.Context, diags *diag.Diagnostics, TagAnnotationMgmtSubnet.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagAnnotationMgmtSubnet.Key.IsUnknown() { + TagAnnotationMgmtSubnet.Key = types.StringNull() + } + if TagAnnotationMgmtSubnet.Value.IsUnknown() { + TagAnnotationMgmtSubnet.Value = types.StringNull() + } TagAnnotationMgmtSubnetList = append(TagAnnotationMgmtSubnetList, TagAnnotationMgmtSubnet) } if childClassName == "tagTag" { @@ -422,6 +454,12 @@ func getAndSetMgmtSubnetAttributes(ctx context.Context, diags *diag.Diagnostics, TagTagMgmtSubnet.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagTagMgmtSubnet.Key.IsUnknown() { + TagTagMgmtSubnet.Key = types.StringNull() + } + if TagTagMgmtSubnet.Value.IsUnknown() { + TagTagMgmtSubnet.Value = types.StringNull() + } TagTagMgmtSubnetList = append(TagTagMgmtSubnetList, TagTagMgmtSubnet) } } @@ -474,17 +512,23 @@ func setMgmtSubnetId(ctx context.Context, data *MgmtSubnetResourceModel) { } func getMgmtSubnetTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtSubnetResourceModel) []map[string]interface{} { - + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} @@ -500,9 +544,11 @@ func getMgmtSubnetTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) } } @@ -512,18 +558,25 @@ func getMgmtSubnetTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di return childPayloads } -func getMgmtSubnetTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagTagPlan, tagTagState []TagTagMgmtSubnetResourceModel) []map[string]interface{} { +func getMgmtSubnetTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagTagPlan, tagTagState []TagTagMgmtSubnetResourceModel) []map[string]interface{} { + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap.Attributes["key"] = tagTag.Key.ValueString() } if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} @@ -539,9 +592,11 @@ func getMgmtSubnetTagTagChildPayloads(ctx context.Context, diags *diag.Diagnosti } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) } } diff --git a/internal/provider/resource_aci_l3out_consumer_label.go b/internal/provider/resource_aci_l3out_consumer_label.go index b3c602508..eb4045a46 100644 --- a/internal/provider/resource_aci_l3out_consumer_label.go +++ b/internal/provider/resource_aci_l3out_consumer_label.go @@ -106,6 +106,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the L3out Consumer Label object.`, @@ -115,6 +116,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The description of the L3out Consumer Label object.`, }, @@ -122,6 +124,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The name of the L3out Consumer Label object.`, @@ -131,6 +134,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the L3out Consumer Label object.`, }, @@ -139,6 +143,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("infra", "tenant"), @@ -150,6 +155,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key for enabling clients to own their data for entity correlation.`, }, @@ -158,6 +164,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `A tag for enabling clients to add their own data. For example, to indicate who created this object.`, }, @@ -166,6 +173,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("alice-blue", "antique-white", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanched-almond", "blue", "blue-violet", "brown", "burlywood", "cadet-blue", "chartreuse", "chocolate", "coral", "cornflower-blue", "cornsilk", "crimson", "cyan", "dark-blue", "dark-cyan", "dark-goldenrod", "dark-gray", "dark-green", "dark-khaki", "dark-magenta", "dark-olive-green", "dark-orange", "dark-orchid", "dark-red", "dark-salmon", "dark-sea-green", "dark-slate-blue", "dark-slate-gray", "dark-turquoise", "dark-violet", "deep-pink", "deep-sky-blue", "dim-gray", "dodger-blue", "fire-brick", "floral-white", "forest-green", "fuchsia", "gainsboro", "ghost-white", "gold", "goldenrod", "gray", "green", "green-yellow", "honeydew", "hot-pink", "indian-red", "indigo", "ivory", "khaki", "lavender", "lavender-blush", "lawn-green", "lemon-chiffon", "light-blue", "light-coral", "light-cyan", "light-goldenrod-yellow", "light-gray", "light-green", "light-pink", "light-salmon", "light-sea-green", "light-sky-blue", "light-slate-gray", "light-steel-blue", "light-yellow", "lime", "lime-green", "linen", "magenta", "maroon", "medium-aquamarine", "medium-blue", "medium-orchid", "medium-purple", "medium-sea-green", "medium-slate-blue", "medium-spring-green", "medium-turquoise", "medium-violet-red", "midnight-blue", "mint-cream", "misty-rose", "moccasin", "navajo-white", "navy", "old-lace", "olive", "olive-drab", "orange", "orange-red", "orchid", "pale-goldenrod", "pale-green", "pale-turquoise", "pale-violet-red", "papaya-whip", "peachpuff", "peru", "pink", "plum", "powder-blue", "purple", "red", "rosy-brown", "royal-blue", "saddle-brown", "salmon", "sandy-brown", "sea-green", "seashell", "sienna", "silver", "sky-blue", "slate-blue", "slate-gray", "snow", "spring-green", "steel-blue", "tan", "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", "white-smoke", "yellow", "yellow-green"), @@ -178,6 +186,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -185,6 +194,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -192,6 +202,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -204,6 +215,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -211,6 +223,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -218,6 +231,7 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -397,7 +411,7 @@ func (r *L3extConsLblResource) ImportState(ctx context.Context, req resource.Imp } func getAndSetL3extConsLblAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *L3extConsLblResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "l3extConsLbl,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -436,6 +450,30 @@ func getAndSetL3extConsLblAttributes(ctx context.Context, diags *diag.Diagnostic data.Tag = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.Descr.IsUnknown() { + data.Descr = types.StringNull() + } + if data.Name.IsUnknown() { + data.Name = types.StringNull() + } + if data.NameAlias.IsUnknown() { + data.NameAlias = types.StringNull() + } + if data.Owner.IsUnknown() { + data.Owner = types.StringNull() + } + if data.OwnerKey.IsUnknown() { + data.OwnerKey = types.StringNull() + } + if data.OwnerTag.IsUnknown() { + data.OwnerTag = types.StringNull() + } + if data.Tag.IsUnknown() { + data.Tag = types.StringNull() + } TagAnnotationL3extConsLblList := make([]TagAnnotationL3extConsLblResourceModel, 0) TagTagL3extConsLblList := make([]TagTagL3extConsLblResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] @@ -454,6 +492,12 @@ func getAndSetL3extConsLblAttributes(ctx context.Context, diags *diag.Diagnostic TagAnnotationL3extConsLbl.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagAnnotationL3extConsLbl.Key.IsUnknown() { + TagAnnotationL3extConsLbl.Key = types.StringNull() + } + if TagAnnotationL3extConsLbl.Value.IsUnknown() { + TagAnnotationL3extConsLbl.Value = types.StringNull() + } TagAnnotationL3extConsLblList = append(TagAnnotationL3extConsLblList, TagAnnotationL3extConsLbl) } if childClassName == "tagTag" { @@ -466,6 +510,12 @@ func getAndSetL3extConsLblAttributes(ctx context.Context, diags *diag.Diagnostic TagTagL3extConsLbl.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagTagL3extConsLbl.Key.IsUnknown() { + TagTagL3extConsLbl.Key = types.StringNull() + } + if TagTagL3extConsLbl.Value.IsUnknown() { + TagTagL3extConsLbl.Value = types.StringNull() + } TagTagL3extConsLblList = append(TagTagL3extConsLblList, TagTagL3extConsLbl) } } @@ -518,17 +568,23 @@ func setL3extConsLblId(ctx context.Context, data *L3extConsLblResourceModel) { } func getL3extConsLblTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extConsLblResourceModel) []map[string]interface{} { - + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} @@ -544,9 +600,11 @@ func getL3extConsLblTagAnnotationChildPayloads(ctx context.Context, diags *diag. } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) } } @@ -556,18 +614,25 @@ func getL3extConsLblTagAnnotationChildPayloads(ctx context.Context, diags *diag. return childPayloads } -func getL3extConsLblTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagTagPlan, tagTagState []TagTagL3extConsLblResourceModel) []map[string]interface{} { +func getL3extConsLblTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagTagPlan, tagTagState []TagTagL3extConsLblResourceModel) []map[string]interface{} { + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap.Attributes["key"] = tagTag.Key.ValueString() } if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} @@ -583,9 +648,11 @@ func getL3extConsLblTagTagChildPayloads(ctx context.Context, diags *diag.Diagnos } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) } } diff --git a/internal/provider/resource_aci_l3out_redistribute_policy.go b/internal/provider/resource_aci_l3out_redistribute_policy.go index 09116d7bc..641058aaa 100644 --- a/internal/provider/resource_aci_l3out_redistribute_policy.go +++ b/internal/provider/resource_aci_l3out_redistribute_policy.go @@ -102,6 +102,7 @@ func (r *L3extRsRedistributePolResource) Schema(ctx context.Context, req resourc Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the L3out Redistribute Policy object.`, @@ -110,6 +111,7 @@ func (r *L3extRsRedistributePolResource) Schema(ctx context.Context, req resourc Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, Validators: []validator.String{ @@ -121,6 +123,7 @@ func (r *L3extRsRedistributePolResource) Schema(ctx context.Context, req resourc Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The name of the Route Control Profile object.`, @@ -131,6 +134,7 @@ func (r *L3extRsRedistributePolResource) Schema(ctx context.Context, req resourc Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -138,6 +142,7 @@ func (r *L3extRsRedistributePolResource) Schema(ctx context.Context, req resourc Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -145,6 +150,7 @@ func (r *L3extRsRedistributePolResource) Schema(ctx context.Context, req resourc Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -157,6 +163,7 @@ func (r *L3extRsRedistributePolResource) Schema(ctx context.Context, req resourc Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -164,6 +171,7 @@ func (r *L3extRsRedistributePolResource) Schema(ctx context.Context, req resourc Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -171,6 +179,7 @@ func (r *L3extRsRedistributePolResource) Schema(ctx context.Context, req resourc Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -350,7 +359,7 @@ func (r *L3extRsRedistributePolResource) ImportState(ctx context.Context, req re } func getAndSetL3extRsRedistributePolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *L3extRsRedistributePolResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "l3extRsRedistributePol,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -374,6 +383,15 @@ func getAndSetL3extRsRedistributePolAttributes(ctx context.Context, diags *diag. data.TnRtctrlProfileName = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.Src.IsUnknown() { + data.Src = types.StringNull() + } + if data.TnRtctrlProfileName.IsUnknown() { + data.TnRtctrlProfileName = types.StringNull() + } TagAnnotationL3extRsRedistributePolList := make([]TagAnnotationL3extRsRedistributePolResourceModel, 0) TagTagL3extRsRedistributePolList := make([]TagTagL3extRsRedistributePolResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] @@ -392,6 +410,12 @@ func getAndSetL3extRsRedistributePolAttributes(ctx context.Context, diags *diag. TagAnnotationL3extRsRedistributePol.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagAnnotationL3extRsRedistributePol.Key.IsUnknown() { + TagAnnotationL3extRsRedistributePol.Key = types.StringNull() + } + if TagAnnotationL3extRsRedistributePol.Value.IsUnknown() { + TagAnnotationL3extRsRedistributePol.Value = types.StringNull() + } TagAnnotationL3extRsRedistributePolList = append(TagAnnotationL3extRsRedistributePolList, TagAnnotationL3extRsRedistributePol) } if childClassName == "tagTag" { @@ -404,6 +428,12 @@ func getAndSetL3extRsRedistributePolAttributes(ctx context.Context, diags *diag. TagTagL3extRsRedistributePol.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagTagL3extRsRedistributePol.Key.IsUnknown() { + TagTagL3extRsRedistributePol.Key = types.StringNull() + } + if TagTagL3extRsRedistributePol.Value.IsUnknown() { + TagTagL3extRsRedistributePol.Value = types.StringNull() + } TagTagL3extRsRedistributePolList = append(TagTagL3extRsRedistributePolList, TagTagL3extRsRedistributePol) } } @@ -456,17 +486,23 @@ func setL3extRsRedistributePolId(ctx context.Context, data *L3extRsRedistributeP } func getL3extRsRedistributePolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsRedistributePolResourceModel) []map[string]interface{} { - + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} @@ -482,9 +518,11 @@ func getL3extRsRedistributePolTagAnnotationChildPayloads(ctx context.Context, di } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) } } @@ -494,18 +532,25 @@ func getL3extRsRedistributePolTagAnnotationChildPayloads(ctx context.Context, di return childPayloads } -func getL3extRsRedistributePolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagTagPlan, tagTagState []TagTagL3extRsRedistributePolResourceModel) []map[string]interface{} { +func getL3extRsRedistributePolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagTagPlan, tagTagState []TagTagL3extRsRedistributePolResourceModel) []map[string]interface{} { + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap.Attributes["key"] = tagTag.Key.ValueString() } if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} @@ -521,9 +566,11 @@ func getL3extRsRedistributePolTagTagChildPayloads(ctx context.Context, diags *di } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) } } diff --git a/internal/provider/resource_aci_out_of_band_contract.go b/internal/provider/resource_aci_out_of_band_contract.go index c0bb85548..ba82ad93e 100644 --- a/internal/provider/resource_aci_out_of_band_contract.go +++ b/internal/provider/resource_aci_out_of_band_contract.go @@ -99,6 +99,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the Out Of Band Contract object.`, @@ -108,6 +109,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The description of the Out Of Band Contract object.`, }, @@ -116,6 +118,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("estimate_add", "estimate_delete", "install"), @@ -126,6 +129,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The name of the Out Of Band Contract object.`, @@ -135,6 +139,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the Out Of Band Contract object.`, }, @@ -143,6 +148,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key for enabling clients to own their data for entity correlation.`, }, @@ -151,6 +157,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `A tag for enabling clients to add their own data. For example, to indicate who created this object.`, }, @@ -159,6 +166,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("level1", "level2", "level3", "level4", "level5", "level6", "unspecified"), @@ -170,6 +178,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("application-profile", "context", "global", "tenant"), @@ -181,6 +190,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("AF11", "AF12", "AF13", "AF21", "AF22", "AF23", "AF31", "AF32", "AF33", "AF41", "AF42", "AF43", "CS0", "CS1", "CS2", "CS3", "CS4", "CS5", "CS6", "CS7", "EF", "VA", "unspecified"), @@ -193,6 +203,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -200,6 +211,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -207,6 +219,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -219,6 +232,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -226,6 +240,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -233,6 +248,7 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -412,7 +428,7 @@ func (r *VzOOBBrCPResource) ImportState(ctx context.Context, req resource.Import } func getAndSetVzOOBBrCPAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *VzOOBBrCPResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "vzOOBBrCP,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -456,6 +472,36 @@ func getAndSetVzOOBBrCPAttributes(ctx context.Context, diags *diag.Diagnostics, data.TargetDscp = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.Descr.IsUnknown() { + data.Descr = types.StringNull() + } + if data.Intent.IsUnknown() { + data.Intent = types.StringNull() + } + if data.Name.IsUnknown() { + data.Name = types.StringNull() + } + if data.NameAlias.IsUnknown() { + data.NameAlias = types.StringNull() + } + if data.OwnerKey.IsUnknown() { + data.OwnerKey = types.StringNull() + } + if data.OwnerTag.IsUnknown() { + data.OwnerTag = types.StringNull() + } + if data.Prio.IsUnknown() { + data.Prio = types.StringNull() + } + if data.Scope.IsUnknown() { + data.Scope = types.StringNull() + } + if data.TargetDscp.IsUnknown() { + data.TargetDscp = types.StringNull() + } TagAnnotationVzOOBBrCPList := make([]TagAnnotationVzOOBBrCPResourceModel, 0) TagTagVzOOBBrCPList := make([]TagTagVzOOBBrCPResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] @@ -474,6 +520,12 @@ func getAndSetVzOOBBrCPAttributes(ctx context.Context, diags *diag.Diagnostics, TagAnnotationVzOOBBrCP.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagAnnotationVzOOBBrCP.Key.IsUnknown() { + TagAnnotationVzOOBBrCP.Key = types.StringNull() + } + if TagAnnotationVzOOBBrCP.Value.IsUnknown() { + TagAnnotationVzOOBBrCP.Value = types.StringNull() + } TagAnnotationVzOOBBrCPList = append(TagAnnotationVzOOBBrCPList, TagAnnotationVzOOBBrCP) } if childClassName == "tagTag" { @@ -486,6 +538,12 @@ func getAndSetVzOOBBrCPAttributes(ctx context.Context, diags *diag.Diagnostics, TagTagVzOOBBrCP.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagTagVzOOBBrCP.Key.IsUnknown() { + TagTagVzOOBBrCP.Key = types.StringNull() + } + if TagTagVzOOBBrCP.Value.IsUnknown() { + TagTagVzOOBBrCP.Value = types.StringNull() + } TagTagVzOOBBrCPList = append(TagTagVzOOBBrCPList, TagTagVzOOBBrCP) } } @@ -522,17 +580,23 @@ func setVzOOBBrCPId(ctx context.Context, data *VzOOBBrCPResourceModel) { } func getVzOOBBrCPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationVzOOBBrCPResourceModel) []map[string]interface{} { - + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} @@ -548,9 +612,11 @@ func getVzOOBBrCPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) } } @@ -560,18 +626,25 @@ func getVzOOBBrCPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia return childPayloads } -func getVzOOBBrCPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagTagPlan, tagTagState []TagTagVzOOBBrCPResourceModel) []map[string]interface{} { +func getVzOOBBrCPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagTagPlan, tagTagState []TagTagVzOOBBrCPResourceModel) []map[string]interface{} { + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap.Attributes["key"] = tagTag.Key.ValueString() } if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} @@ -587,9 +660,11 @@ func getVzOOBBrCPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostic } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) } } diff --git a/internal/provider/resource_aci_pim_route_map_entry.go b/internal/provider/resource_aci_pim_route_map_entry.go index 1a05ea464..bf845aeb5 100644 --- a/internal/provider/resource_aci_pim_route_map_entry.go +++ b/internal/provider/resource_aci_pim_route_map_entry.go @@ -107,6 +107,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("deny", "permit"), @@ -118,6 +119,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the Pim Route Map Entry object.`, @@ -127,6 +129,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The description of the Pim Route Map Entry object.`, }, @@ -135,6 +138,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The group ip of the Pim Route Map Entry object.`, }, @@ -143,6 +147,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name of the Pim Route Map Entry object.`, }, @@ -151,6 +156,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the Pim Route Map Entry object.`, }, @@ -158,6 +164,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `PIM route map entry order.`, @@ -167,6 +174,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The rendezvous point ip of the Pim Route Map Entry object.`, }, @@ -175,6 +183,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The source ip of the Pim Route Map Entry object.`, }, @@ -184,6 +193,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -191,6 +201,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -198,6 +209,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -210,6 +222,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -217,6 +230,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -224,6 +238,7 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -403,7 +418,7 @@ func (r *PimRouteMapEntryResource) ImportState(ctx context.Context, req resource } func getAndSetPimRouteMapEntryAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *PimRouteMapEntryResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "pimRouteMapEntry,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -445,6 +460,33 @@ func getAndSetPimRouteMapEntryAttributes(ctx context.Context, diags *diag.Diagno data.Src = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Action.IsUnknown() { + data.Action = types.StringNull() + } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.Descr.IsUnknown() { + data.Descr = types.StringNull() + } + if data.Grp.IsUnknown() { + data.Grp = types.StringNull() + } + if data.Name.IsUnknown() { + data.Name = types.StringNull() + } + if data.NameAlias.IsUnknown() { + data.NameAlias = types.StringNull() + } + if data.Order.IsUnknown() { + data.Order = types.StringNull() + } + if data.Rp.IsUnknown() { + data.Rp = types.StringNull() + } + if data.Src.IsUnknown() { + data.Src = types.StringNull() + } TagAnnotationPimRouteMapEntryList := make([]TagAnnotationPimRouteMapEntryResourceModel, 0) TagTagPimRouteMapEntryList := make([]TagTagPimRouteMapEntryResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] @@ -463,6 +505,12 @@ func getAndSetPimRouteMapEntryAttributes(ctx context.Context, diags *diag.Diagno TagAnnotationPimRouteMapEntry.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagAnnotationPimRouteMapEntry.Key.IsUnknown() { + TagAnnotationPimRouteMapEntry.Key = types.StringNull() + } + if TagAnnotationPimRouteMapEntry.Value.IsUnknown() { + TagAnnotationPimRouteMapEntry.Value = types.StringNull() + } TagAnnotationPimRouteMapEntryList = append(TagAnnotationPimRouteMapEntryList, TagAnnotationPimRouteMapEntry) } if childClassName == "tagTag" { @@ -475,6 +523,12 @@ func getAndSetPimRouteMapEntryAttributes(ctx context.Context, diags *diag.Diagno TagTagPimRouteMapEntry.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagTagPimRouteMapEntry.Key.IsUnknown() { + TagTagPimRouteMapEntry.Key = types.StringNull() + } + if TagTagPimRouteMapEntry.Value.IsUnknown() { + TagTagPimRouteMapEntry.Value = types.StringNull() + } TagTagPimRouteMapEntryList = append(TagTagPimRouteMapEntryList, TagTagPimRouteMapEntry) } } @@ -527,17 +581,23 @@ func setPimRouteMapEntryId(ctx context.Context, data *PimRouteMapEntryResourceMo } func getPimRouteMapEntryTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapEntryResourceModel) []map[string]interface{} { - + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} @@ -553,9 +613,11 @@ func getPimRouteMapEntryTagAnnotationChildPayloads(ctx context.Context, diags *d } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) } } @@ -565,18 +627,25 @@ func getPimRouteMapEntryTagAnnotationChildPayloads(ctx context.Context, diags *d return childPayloads } -func getPimRouteMapEntryTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagTagPlan, tagTagState []TagTagPimRouteMapEntryResourceModel) []map[string]interface{} { +func getPimRouteMapEntryTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagTagPlan, tagTagState []TagTagPimRouteMapEntryResourceModel) []map[string]interface{} { + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap.Attributes["key"] = tagTag.Key.ValueString() } if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} @@ -592,9 +661,11 @@ func getPimRouteMapEntryTagTagChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) } } diff --git a/internal/provider/resource_aci_pim_route_map_policy.go b/internal/provider/resource_aci_pim_route_map_policy.go index c63bb3e79..05a7c78fe 100644 --- a/internal/provider/resource_aci_pim_route_map_policy.go +++ b/internal/provider/resource_aci_pim_route_map_policy.go @@ -102,6 +102,7 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the Pim Route Map Policy object.`, @@ -111,6 +112,7 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The description of the Pim Route Map Policy object.`, }, @@ -118,6 +120,7 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The name of the Pim Route Map Policy object.`, @@ -127,6 +130,7 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the Pim Route Map Policy object.`, }, @@ -135,6 +139,7 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key for enabling clients to own their data for entity correlation.`, }, @@ -143,6 +148,7 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `A tag for enabling clients to add their own data. For example, to indicate who created this object.`, }, @@ -152,6 +158,7 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -159,6 +166,7 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -166,6 +174,7 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -178,6 +187,7 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -185,6 +195,7 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -192,6 +203,7 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -371,7 +383,7 @@ func (r *PimRouteMapPolResource) ImportState(ctx context.Context, req resource.I } func getAndSetPimRouteMapPolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *PimRouteMapPolResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "pimRouteMapPol,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -404,6 +416,24 @@ func getAndSetPimRouteMapPolAttributes(ctx context.Context, diags *diag.Diagnost data.OwnerTag = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.Descr.IsUnknown() { + data.Descr = types.StringNull() + } + if data.Name.IsUnknown() { + data.Name = types.StringNull() + } + if data.NameAlias.IsUnknown() { + data.NameAlias = types.StringNull() + } + if data.OwnerKey.IsUnknown() { + data.OwnerKey = types.StringNull() + } + if data.OwnerTag.IsUnknown() { + data.OwnerTag = types.StringNull() + } TagAnnotationPimRouteMapPolList := make([]TagAnnotationPimRouteMapPolResourceModel, 0) TagTagPimRouteMapPolList := make([]TagTagPimRouteMapPolResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] @@ -422,6 +452,12 @@ func getAndSetPimRouteMapPolAttributes(ctx context.Context, diags *diag.Diagnost TagAnnotationPimRouteMapPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagAnnotationPimRouteMapPol.Key.IsUnknown() { + TagAnnotationPimRouteMapPol.Key = types.StringNull() + } + if TagAnnotationPimRouteMapPol.Value.IsUnknown() { + TagAnnotationPimRouteMapPol.Value = types.StringNull() + } TagAnnotationPimRouteMapPolList = append(TagAnnotationPimRouteMapPolList, TagAnnotationPimRouteMapPol) } if childClassName == "tagTag" { @@ -434,6 +470,12 @@ func getAndSetPimRouteMapPolAttributes(ctx context.Context, diags *diag.Diagnost TagTagPimRouteMapPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagTagPimRouteMapPol.Key.IsUnknown() { + TagTagPimRouteMapPol.Key = types.StringNull() + } + if TagTagPimRouteMapPol.Value.IsUnknown() { + TagTagPimRouteMapPol.Value = types.StringNull() + } TagTagPimRouteMapPolList = append(TagTagPimRouteMapPolList, TagTagPimRouteMapPol) } } @@ -486,17 +528,23 @@ func setPimRouteMapPolId(ctx context.Context, data *PimRouteMapPolResourceModel) } func getPimRouteMapPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapPolResourceModel) []map[string]interface{} { - + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} @@ -512,9 +560,11 @@ func getPimRouteMapPolTagAnnotationChildPayloads(ctx context.Context, diags *dia } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) } } @@ -524,18 +574,25 @@ func getPimRouteMapPolTagAnnotationChildPayloads(ctx context.Context, diags *dia return childPayloads } -func getPimRouteMapPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagTagPlan, tagTagState []TagTagPimRouteMapPolResourceModel) []map[string]interface{} { +func getPimRouteMapPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagTagPlan, tagTagState []TagTagPimRouteMapPolResourceModel) []map[string]interface{} { + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap.Attributes["key"] = tagTag.Key.ValueString() } if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} @@ -551,9 +608,11 @@ func getPimRouteMapPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagn } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) } } diff --git a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go index 8458e5ebb..67a94be36 100644 --- a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go +++ b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go @@ -101,6 +101,7 @@ func (r *MgmtRsOoBConsResource) Schema(ctx context.Context, req resource.SchemaR Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the Relation To Consumed Out Of Band Contract object.`, @@ -110,6 +111,7 @@ func (r *MgmtRsOoBConsResource) Schema(ctx context.Context, req resource.SchemaR Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("level1", "level2", "level3", "level4", "level5", "level6", "unspecified"), @@ -120,6 +122,7 @@ func (r *MgmtRsOoBConsResource) Schema(ctx context.Context, req resource.SchemaR Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The name of the Out Of Band Contract object.`, @@ -130,6 +133,7 @@ func (r *MgmtRsOoBConsResource) Schema(ctx context.Context, req resource.SchemaR Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -137,6 +141,7 @@ func (r *MgmtRsOoBConsResource) Schema(ctx context.Context, req resource.SchemaR Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -144,6 +149,7 @@ func (r *MgmtRsOoBConsResource) Schema(ctx context.Context, req resource.SchemaR Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -156,6 +162,7 @@ func (r *MgmtRsOoBConsResource) Schema(ctx context.Context, req resource.SchemaR Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -163,6 +170,7 @@ func (r *MgmtRsOoBConsResource) Schema(ctx context.Context, req resource.SchemaR Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -170,6 +178,7 @@ func (r *MgmtRsOoBConsResource) Schema(ctx context.Context, req resource.SchemaR Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -349,7 +358,7 @@ func (r *MgmtRsOoBConsResource) ImportState(ctx context.Context, req resource.Im } func getAndSetMgmtRsOoBConsAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *MgmtRsOoBConsResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtRsOoBCons,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -373,6 +382,15 @@ func getAndSetMgmtRsOoBConsAttributes(ctx context.Context, diags *diag.Diagnosti data.TnVzOOBBrCPName = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.Prio.IsUnknown() { + data.Prio = types.StringNull() + } + if data.TnVzOOBBrCPName.IsUnknown() { + data.TnVzOOBBrCPName = types.StringNull() + } TagAnnotationMgmtRsOoBConsList := make([]TagAnnotationMgmtRsOoBConsResourceModel, 0) TagTagMgmtRsOoBConsList := make([]TagTagMgmtRsOoBConsResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] @@ -391,6 +409,12 @@ func getAndSetMgmtRsOoBConsAttributes(ctx context.Context, diags *diag.Diagnosti TagAnnotationMgmtRsOoBCons.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagAnnotationMgmtRsOoBCons.Key.IsUnknown() { + TagAnnotationMgmtRsOoBCons.Key = types.StringNull() + } + if TagAnnotationMgmtRsOoBCons.Value.IsUnknown() { + TagAnnotationMgmtRsOoBCons.Value = types.StringNull() + } TagAnnotationMgmtRsOoBConsList = append(TagAnnotationMgmtRsOoBConsList, TagAnnotationMgmtRsOoBCons) } if childClassName == "tagTag" { @@ -403,6 +427,12 @@ func getAndSetMgmtRsOoBConsAttributes(ctx context.Context, diags *diag.Diagnosti TagTagMgmtRsOoBCons.Value = basetypes.NewStringValue(childAttributeValue.(string)) } } + if TagTagMgmtRsOoBCons.Key.IsUnknown() { + TagTagMgmtRsOoBCons.Key = types.StringNull() + } + if TagTagMgmtRsOoBCons.Value.IsUnknown() { + TagTagMgmtRsOoBCons.Value = types.StringNull() + } TagTagMgmtRsOoBConsList = append(TagTagMgmtRsOoBConsList, TagTagMgmtRsOoBCons) } } @@ -455,17 +485,23 @@ func setMgmtRsOoBConsId(ctx context.Context, data *MgmtRsOoBConsResourceModel) { } func getMgmtRsOoBConsTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtRsOoBConsResourceModel) []map[string]interface{} { - + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} @@ -481,9 +517,11 @@ func getMgmtRsOoBConsTagAnnotationChildPayloads(ctx context.Context, diags *diag } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) } } @@ -493,18 +531,25 @@ func getMgmtRsOoBConsTagAnnotationChildPayloads(ctx context.Context, diags *diag return childPayloads } -func getMgmtRsOoBConsTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagTagPlan, tagTagState []TagTagMgmtRsOoBConsResourceModel) []map[string]interface{} { +func getMgmtRsOoBConsTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagTagPlan, tagTagState []TagTagMgmtRsOoBConsResourceModel) []map[string]interface{} { + type childMapType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` + } + childMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap.Attributes["key"] = tagTag.Key.ValueString() } if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} @@ -520,9 +565,11 @@ func getMgmtRsOoBConsTagTagChildPayloads(ctx context.Context, diags *diag.Diagno } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() + childMap := childMapType{ + Attributes: make(map[string]interface{}), + } + childMap.Attributes["status"] = "deleted" + childMap.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) } } diff --git a/internal/provider/resource_aci_tag.go b/internal/provider/resource_aci_tag.go index 839aa221e..c9471d273 100644 --- a/internal/provider/resource_aci_tag.go +++ b/internal/provider/resource_aci_tag.go @@ -81,6 +81,7 @@ func (r *TagTagResource) Schema(ctx context.Context, req resource.SchemaRequest, Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, @@ -89,6 +90,7 @@ func (r *TagTagResource) Schema(ctx context.Context, req resource.SchemaRequest, Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -267,6 +269,12 @@ func getAndSetTagTagAttributes(ctx context.Context, diags *diag.Diagnostics, cli data.Value = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Key.IsUnknown() { + data.Key = types.StringNull() + } + if data.Value.IsUnknown() { + data.Value = types.StringNull() + } } else { diags.AddError( "too many results in response", diff --git a/internal/provider/utils.go b/internal/provider/utils.go index 080f85d76..168a2ba2d 100644 --- a/internal/provider/utils.go +++ b/internal/provider/utils.go @@ -3,6 +3,7 @@ package provider import ( "context" "fmt" + "log" "net/http" "strings" @@ -10,6 +11,8 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/ciscoecosystem/aci-go-client/v2/models" "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" ) @@ -103,3 +106,50 @@ func GetDeleteJsonPayload(ctx context.Context, diags *diag.Diagnostics, classNam } return jsonPayload } + +type setToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate struct{} + +func SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate() planmodifier.String { + return setToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate{} +} + +func (m setToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate) Description(_ context.Context) string { + return "During the update phase, set the value of this attribute to StringNull when the state value is null and the plan value is unknown." +} + +func (m setToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate) MarkdownDescription(_ context.Context) string { + return "During the update phase, set the value of this attribute to StringNull when the state value is null and the plan value is unknown." +} + +// Custom plan modifier to set the plan value to null under certain conditions +func (m setToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { + // Set the plan value to StringType 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.StringNull() + } + return +} + +type setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate struct{} + +func SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate() planmodifier.Set { + return setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate{} +} + +func (m setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate) Description(_ context.Context) string { + return "During the update phase, set the value of this attribute to SetNull when the state value is null and the plan value is unknown." +} + +func (m setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate) MarkdownDescription(_ context.Context) string { + return "During the update phase, set the value of this attribute to SetNull when the state value is null and the plan value is unknown." +} + +// Custom plan modifier to set the plan value to null under certain conditions +func (m setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate) PlanModifySet(ctx context.Context, req planmodifier.SetRequest, resp *planmodifier.SetResponse) { + // Set the plan value to SetType null when state value is null and plan value is unknown during an Update + log.Printf("heretstaeval %v;herestate unknown %v; herestate null %v;hereplanval %v, hereplan unknown %v, hereplan null %v", req.StateValue, req.StateValue.IsUnknown(), req.StateValue.IsNull(), req.PlanValue, req.PlanValue.IsUnknown(), req.PlanValue.IsNull()) + if !req.State.Raw.IsNull() && req.StateValue.IsNull() && req.PlanValue.IsUnknown() { + resp.PlanValue = types.SetNull(req.PlanValue.ElementType(ctx)) + } + return +} From 1b2300d11dd44bdc6d37654e478c3d0427a69b6d Mon Sep 17 00:00:00 2001 From: Shreyas Date: Tue, 16 Apr 2024 18:37:21 -0400 Subject: [PATCH 04/20] [ignore] Made changes to resource for testing Read function --- gen/templates/resource.go.tmpl | 15 + .../resource_aci_communication_policy.go | 449 +++++++++++++----- internal/provider/utils.go | 74 ++- 3 files changed, 404 insertions(+), 134 deletions(-) diff --git a/gen/templates/resource.go.tmpl b/gen/templates/resource.go.tmpl index 85ecff606..864e42f42 100644 --- a/gen/templates/resource.go.tmpl +++ b/gen/templates/resource.go.tmpl @@ -981,6 +981,21 @@ for childAttributeName, childAttributeValue := range {{.PkgName}}childAttributeV {{- template "getAndSetGrandChildren" . }} } {{- end}} + {{- range .Properties}} + if {{.ResourceClassName}}{{$.ParentName}}.{{.Name}}.IsNull() { + {{- if eq .ValueType "bitmask"}} + var data{{.PropertyName}}{{.ResourceClassName}}{{$.ResourceClassName}} []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel + data.{{.ResourceClassName}}.ElementsAs(ctx,&data{{.PropertyName}}{{.ResourceClassName}}{{$.ResourceClassName}},false) + for _, {{.ResourceClassName | lowerFirstCharacter}} := range data{{.PropertyName}}{{.ResourceClassName}}{{$.ResourceClassName}} { + if {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}}.IsNull(){ + {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}} = types.SetUnknown({{.ResourceClassName | lowerFirstCharacter}}.{{.Name}}.ElementType(ctx)) + } + } + {{- else}} + {{.ResourceClassName}}{{$.ParentName}}.{{.Name}} = types.StringUnknown() + {{- end}} + } + {{- end}} } {{- if .IdentifiedBy}} {{.ResourceClassName}}{{$.ParentName}}List = append({{.ResourceClassName}}{{$.ParentName}}List, {{.ResourceClassName}}{{$.ParentName}}) diff --git a/internal/provider/resource_aci_communication_policy.go b/internal/provider/resource_aci_communication_policy.go index ee08464c6..b760b908a 100644 --- a/internal/provider/resource_aci_communication_policy.go +++ b/internal/provider/resource_aci_communication_policy.go @@ -8,6 +8,7 @@ import ( "context" "encoding/json" "fmt" + "log" "reflect" "strings" @@ -15,6 +16,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -85,18 +87,105 @@ type CommHttpsCommPolResourceModel struct { CommRsKeyRing types.Set `tfsdk:"key_ring"` } +func NewCommHttpsCommPolResourceModel() *CommHttpsCommPolResourceModel { + return &CommHttpsCommPolResourceModel{ + AccessControlAllowCredential: types.StringNull(), + AccessControlAllowOrigins: types.StringNull(), + AdminSt: types.StringNull(), + Annotation: types.StringNull(), + CliOnlyMode: types.StringNull(), + ClientCertAuthState: types.StringNull(), + Descr: types.StringNull(), + DhParam: types.StringNull(), + GlobalThrottleRate: types.StringNull(), + GlobalThrottleSt: types.StringNull(), + GlobalThrottleUnit: types.StringNull(), + MaxRequestStatusCount: types.StringNull(), + Name: types.StringNull(), + NameAlias: types.StringNull(), + NodeExporter: types.StringNull(), + Port: types.StringNull(), + Referer: types.StringNull(), + ServerHeader: types.StringNull(), + SslProtocols: types.SetNull(types.StringType), + ThrottleRate: types.StringNull(), + ThrottleSt: types.StringNull(), + VisoreAccess: types.StringNull(), + CommRsClientCertCA: types.SetNull(types.SetType{}), + CommRsKeyRing: types.SetNull(types.SetType{}), + + } +} + +func (m CommHttpsCommPolResourceModel) AttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "access_control_allow_credential": types.StringType, + "access_control_allow_origins": types.StringType, + "admin_st": types.StringType, + "annotation": types.StringType, + "cli_only_mode": types.StringType, + "client_cert_auth_state": types.StringType, + "description": types.StringType, + "dh_param": types.StringType, + "global_throttle_rate": types.StringType, + "global_throttle_st": types.StringType, + "global_throttle_unit": types.StringType, + "max_request_status_count": types.StringType, + "name": types.StringType, + "name_alias": types.StringType, + "node_exporter": types.StringType, + "port": types.StringType, + "referer": types.StringType, + "server_header": types.StringType, + "ssl_protocols": types.SetType{ElemType: types.StringType}, + "throttle_rate": types.StringType, + "throttle_st": types.StringType, + "visore_access": types.StringType, + "tp": types.SetType{ElemType: types.StringType}, + "key_ring": types.SetType{ElemType: types.StringType}, + } +} + // CommRsClientCertCACommHttpsResourceModel describes the resource data model for the children without relation ships. type CommRsClientCertCACommHttpsResourceModel struct { Annotation types.String `tfsdk:"annotation"` TDn types.String `tfsdk:"target_dn"` } +func CommRsClientCertCACommHttpsResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "annotation": types.StringType, + "target_dn": types.StringType, + } +} + +func NewCommRsClientCertCACommHttpsResourceModel() *CommRsClientCertCACommHttpsResourceModel { + return &CommRsClientCertCACommHttpsResourceModel{ + Annotation: types.StringNull(), + TDn: types.StringNull(), + } +} + // CommRsKeyRingCommHttpsResourceModel describes the resource data model for the children without relation ships. type CommRsKeyRingCommHttpsResourceModel struct { Annotation types.String `tfsdk:"annotation"` TnPkiKeyRingName types.String `tfsdk:"tn_pki_key_ring_name"` } +func (m CommRsKeyRingCommHttpsResourceModel) AttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "annotation": types.StringType, + "tn_pki_key_ring_name": types.StringType, + } +} + +func NewCommRsKeyRingCommHttpsResourceModel() *CommRsKeyRingCommHttpsResourceModel { + return &CommRsKeyRingCommHttpsResourceModel{ + Annotation: types.StringNull(), + TnPkiKeyRingName: types.StringNull(), + } +} + // TagAnnotationCommPolResourceModel describes the resource data model for the children without relation ships. type TagAnnotationCommPolResourceModel struct { Key types.String `tfsdk:"key"` @@ -454,7 +543,8 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - //SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, Validators: []validator.Set{ setvalidator.SizeAtMost(1), @@ -466,7 +556,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + //SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The annotation of the Tp object.`, }, @@ -475,7 +565,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + //SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The distinguished name of the target.`, }, @@ -489,6 +579,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, Validators: []validator.Set{ setvalidator.SizeAtMost(1), @@ -525,7 +616,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -554,7 +645,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -813,8 +904,13 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl data.StrictSecurityOnApicOOBSubnet = types.StringNull() } CommHttpsCommPolList := make([]CommHttpsCommPolResourceModel, 1) - CommRsClientCertCACommHttpsList := make([]CommRsClientCertCACommHttpsResourceModel, 1) + var CommHttpsCommPol CommHttpsCommPolResourceModel + //CommRsClientCertCACommHttpsList := make([]CommRsClientCertCACommHttpsResourceModel, 1) + //var CommRsClientCertCACommHttps2 CommRsClientCertCACommHttpsResourceModel + //var CommRsClientCertCAObject basetypes.ObjectValue + CommRsClientCertCAObject:=types.ObjectNull(CommRsClientCertCACommHttpsResourceModelAttributeTypes()) CommRsKeyRingCommHttpsList := make([]CommRsKeyRingCommHttpsResourceModel, 1) + var CommRsKeyRingCommHttps CommRsKeyRingCommHttpsResourceModel TagAnnotationCommPolList := make([]TagAnnotationCommPolResourceModel, 0) TagTagCommPolList := make([]TagTagCommPolResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] @@ -824,7 +920,7 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "commHttps" { - CommHttpsCommPol := CommHttpsCommPolResourceModel{} + // CommHttpsCommPol := CommHttpsCommPolResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "accessControlAllowCredential" { CommHttpsCommPol.AccessControlAllowCredential = basetypes.NewStringValue(childAttributeValue.(string)) @@ -901,33 +997,83 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl CommHttpsCommPol.VisoreAccess = basetypes.NewStringValue(childAttributeValue.(string)) } childClassesCommHttps := childClassDetails.(map[string]interface{})["children"].([]interface{}) - for _, childCommHttps := range childClassesCommHttps { - for childClassNameCommHttps, childClassDetailsCommHttps := range childCommHttps.(map[string]interface{}) { - if childClassNameCommHttps == "commRsClientCertCA" { - CommRsClientCertCACommHttps := CommRsClientCertCACommHttpsResourceModel{} - commRsClientCertCAchildAttributeValue := childClassDetailsCommHttps.(map[string]interface{})["attributes"].(map[string]interface{}) - for childAttributeName, childAttributeValue := range commRsClientCertCAchildAttributeValue { - if childAttributeName == "annotation" { - CommRsClientCertCACommHttps.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) + + // for _, childCommHttps := range childClassesCommHttps { + // for childClassNameCommHttps, childClassDetailsCommHttps := range childCommHttps.(map[string]interface{}) { + // if childClassNameCommHttps == "commRsClientCertCA" { + // CommRsClientCertCACommHttps := CommRsClientCertCACommHttpsResourceModel{} + + // commRsClientCertCAchildAttributeValue := childClassDetailsCommHttps.(map[string]interface{})["attributes"].(map[string]interface{}) + // for childAttributeName, childAttributeValue := range commRsClientCertCAchildAttributeValue { + // if childAttributeName == "annotation" { + // CommRsClientCertCACommHttps.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) + // } + // if childAttributeName == "tDn" { + // CommRsClientCertCACommHttps.TDn = basetypes.NewStringValue(childAttributeValue.(string)) + // } + // if CommRsClientCertCACommHttps.Annotation.IsUnknown() { + // CommRsClientCertCACommHttps.Annotation = types.StringNull(), + // } + // if CommRsClientCertCACommHttps.TDn.IsUnknown() { + // CommRsClientCertCACommHttps.TDn = types.StringNull(), + // } + // } + // CommRsClientCertCACommHttpsList[0] = CommRsClientCertCACommHttps + // CommHttpsCommPol.CommRsClientCertCA, _ = types.SetValueFrom(ctx, CommHttpsCommPol.CommRsClientCertCA.ElementType(ctx), CommRsClientCertCACommHttpsList) + // } + + + + // type ObjectAsOptions struct { + // // UnhandledNullAsEmpty controls what happens when As needs to put a + // // null value in a type that has no way to preserve that distinction. + // // When set to true, the type's empty value will be used. When set to + // // false, an error will be returned. + // UnhandledNullAsEmpty bool + + // // UnhandledUnknownAsEmpty controls what happens when As needs to put + // // an unknown value in a type that has no way to preserve that + // // distinction. When set to true, the type's empty value will be used. + // // When set to false, an error will be returned. + // UnhandledUnknownAsEmpty bool + // } + + for _, childCommHttps := range childClassesCommHttps { + for childClassNameCommHttps, childClassDetailsCommHttps := range childCommHttps.(map[string]interface{}) { + if childClassNameCommHttps == "commRsClientCertCA" { + var CommRsClientCertCACommHttps CommRsClientCertCACommHttpsResourceModel + commRsClientCertCAchildAttributes := childClassDetailsCommHttps.(map[string]interface{})["attributes"].(map[string]interface{}) + + // Set the known attributes. + if annotation, ok := commRsClientCertCAchildAttributes["annotation"].(string); ok { + CommRsClientCertCACommHttps.Annotation = basetypes.NewStringValue(annotation) + } + if tDn, ok := commRsClientCertCAchildAttributes["tDn"].(string); ok { + CommRsClientCertCACommHttps.TDn = basetypes.NewStringValue(tDn) + } + + CommRsClientCertCAObject, _ = types.ObjectValueFrom(ctx, CommRsClientCertCACommHttpsResourceModelAttributeTypes(), CommRsClientCertCACommHttps) + } - if childAttributeName == "tDn" { - CommRsClientCertCACommHttps.TDn = basetypes.NewStringValue(childAttributeValue.(string)) - } - } - CommRsClientCertCACommHttpsList[0] = CommRsClientCertCACommHttps - CommHttpsCommPol.CommRsClientCertCA, _ = types.SetValueFrom(ctx, CommHttpsCommPol.CommRsClientCertCA.ElementType(ctx), CommRsClientCertCACommHttpsList) - } - var dataCommRsClientCertCACommHttpsCommPol []CommHttpsCommPolResourceModel - data.CommHttps.ElementsAs(ctx, &dataCommRsClientCertCACommHttpsCommPol, false) - for _, commHttps := range dataCommRsClientCertCACommHttpsCommPol { - CommRsClientCertCASet, _ := types.SetValueFrom(ctx, commHttps.CommRsClientCertCA.ElementType(ctx), CommRsClientCertCACommHttpsList) - CommHttpsCommPol.CommRsClientCertCA = CommRsClientCertCASet - if commHttps.CommRsClientCertCA.IsUnknown() { - CommHttpsCommPol.CommRsClientCertCA = types.SetNull(commHttps.CommRsClientCertCA.ElementType(ctx)) - } - } + + // if CommHttpsCommPol.CommRsClientCertCA.IsUnknown() || CommHttpsCommPol.CommRsClientCertCA.IsNull() { + + // CommHttpsCommPol.CommRsClientCertCA = types.ObjectNull(CommRsClientCertCACommHttps.AttributeTypes()) + // } + + // var dataCommRsClientCertCACommHttpsCommPol []CommHttpsCommPolResourceModel + // data.CommHttps.ElementsAs(ctx, &dataCommRsClientCertCACommHttpsCommPol, false) + // for _, commHttps := range dataCommRsClientCertCACommHttpsCommPol { + // // CommRsClientCertCAObject, _ := types.SetValueFrom(ctx, commHttps.CommRsClientCertCA.ElementType(ctx), CommRsClientCertCACommHttpsList) + // // CommHttpsCommPol.CommRsClientCertCA = CommRsClientCertCAObject + // log.Printf("Here %v",commHttps.CommRsClientCertCA.ElementType(ctx)) + // if commHttps.CommRsClientCertCA.IsUnknown() || commHttps.CommRsClientCertCA.IsNull() { + + // CommHttpsCommPol.CommRsClientCertCA = types.SetNull(commHttps.CommRsClientCertCA.ElementType(ctx)) + // } + // } if childClassNameCommHttps == "commRsKeyRing" { - CommRsKeyRingCommHttps := CommRsKeyRingCommHttpsResourceModel{} + // CommRsKeyRingCommHttps := CommRsKeyRingCommHttpsResourceModel{} commRsKeyRingchildAttributeValue := childClassDetailsCommHttps.(map[string]interface{})["attributes"].(map[string]interface{}) for childAttributeName, childAttributeValue := range commRsKeyRingchildAttributeValue { if childAttributeName == "annotation" { @@ -936,94 +1082,135 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl if childAttributeName == "tnPkiKeyRingName" { CommRsKeyRingCommHttps.TnPkiKeyRingName = basetypes.NewStringValue(childAttributeValue.(string)) } + // if CommRsKeyRingCommHttps.Annotation.IsUnknown() { + // CommRsKeyRingCommHttps.Annotation = types.StringNull(), + // } + // if CommRsKeyRingCommHttps.TnPkiKeyRingName.IsUnknown() { + // CommRsKeyRingCommHttps.TnPkiKeyRingName = types.StringNull(), + // } } CommRsKeyRingCommHttpsList[0] = CommRsKeyRingCommHttps - CommHttpsCommPol.CommRsKeyRing, _ = types.SetValueFrom(ctx, CommHttpsCommPol.CommRsKeyRing.ElementType(ctx), CommRsKeyRingCommHttpsList) + //CommHttpsCommPol.CommRsKeyRing, _ = types.SetValueFrom(ctx, CommHttpsCommPol.CommRsKeyRing.ElementType(ctx), CommRsKeyRingCommHttpsList) } - var dataCommRsKeyRingCommHttpsCommPol []CommHttpsCommPolResourceModel - data.CommHttps.ElementsAs(ctx, &dataCommRsKeyRingCommHttpsCommPol, false) - for _, commHttps := range dataCommRsKeyRingCommHttpsCommPol { - CommRsKeyRingSet, _ := types.SetValueFrom(ctx, commHttps.CommRsKeyRing.ElementType(ctx), CommRsKeyRingCommHttpsList) - CommHttpsCommPol.CommRsKeyRing = CommRsKeyRingSet - if commHttps.CommRsKeyRing.IsUnknown() { - CommHttpsCommPol.CommRsKeyRing = types.SetNull(commHttps.CommRsKeyRing.ElementType(ctx)) - } - } - } - } - } - if CommHttpsCommPol.AccessControlAllowCredential.IsUnknown() { - CommHttpsCommPol.AccessControlAllowCredential = types.StringNull() - } - if CommHttpsCommPol.AccessControlAllowOrigins.IsUnknown() { - CommHttpsCommPol.AccessControlAllowOrigins = types.StringNull() - } - if CommHttpsCommPol.AdminSt.IsUnknown() { - CommHttpsCommPol.AdminSt = types.StringNull() - } - if CommHttpsCommPol.Annotation.IsUnknown() { - CommHttpsCommPol.Annotation = types.StringNull() - } - if CommHttpsCommPol.CliOnlyMode.IsUnknown() { - CommHttpsCommPol.CliOnlyMode = types.StringNull() - } - if CommHttpsCommPol.ClientCertAuthState.IsUnknown() { - CommHttpsCommPol.ClientCertAuthState = types.StringNull() - } - if CommHttpsCommPol.Descr.IsUnknown() { - CommHttpsCommPol.Descr = types.StringNull() - } - if CommHttpsCommPol.DhParam.IsUnknown() { - CommHttpsCommPol.DhParam = types.StringNull() - } - if CommHttpsCommPol.GlobalThrottleRate.IsUnknown() { - CommHttpsCommPol.GlobalThrottleRate = types.StringNull() - } - if CommHttpsCommPol.GlobalThrottleSt.IsUnknown() { - CommHttpsCommPol.GlobalThrottleSt = types.StringNull() - } - if CommHttpsCommPol.GlobalThrottleUnit.IsUnknown() { - CommHttpsCommPol.GlobalThrottleUnit = types.StringNull() - } - if CommHttpsCommPol.MaxRequestStatusCount.IsUnknown() { - CommHttpsCommPol.MaxRequestStatusCount = types.StringNull() - } - if CommHttpsCommPol.Name.IsUnknown() { - CommHttpsCommPol.Name = types.StringNull() - } - if CommHttpsCommPol.NameAlias.IsUnknown() { - CommHttpsCommPol.NameAlias = types.StringNull() - } - if CommHttpsCommPol.NodeExporter.IsUnknown() { - CommHttpsCommPol.NodeExporter = types.StringNull() - } - if CommHttpsCommPol.Port.IsUnknown() { - CommHttpsCommPol.Port = types.StringNull() - } - if CommHttpsCommPol.Referer.IsUnknown() { - CommHttpsCommPol.Referer = types.StringNull() - } - if CommHttpsCommPol.ServerHeader.IsUnknown() { - CommHttpsCommPol.ServerHeader = types.StringNull() - } - if CommHttpsCommPol.SslProtocols.IsUnknown() { - var datasslProtocolsCommHttpsCommPol []CommHttpsCommPolResourceModel - data.CommHttps.ElementsAs(ctx, &datasslProtocolsCommHttpsCommPol, false) - for _, commHttps := range datasslProtocolsCommHttpsCommPol { - if CommHttpsCommPol.SslProtocols.IsUnknown() { - CommHttpsCommPol.SslProtocols = types.SetNull(commHttps.SslProtocols.ElementType(ctx)) + // var dataCommRsKeyRingCommHttpsCommPol []CommHttpsCommPolResourceModel + // data.CommHttps.ElementsAs(ctx, &dataCommRsKeyRingCommHttpsCommPol, false) + // for _, commHttps := range dataCommRsKeyRingCommHttpsCommPol { + // CommRsKeyRingObject, _ := types.SetValueFrom(ctx, commHttps.CommRsKeyRing.ElementType(ctx), CommRsKeyRingCommHttpsList) + // CommHttpsCommPol.CommRsKeyRing = CommRsKeyRingObject + // if commHttps.CommRsKeyRing.IsUnknown() { + // CommHttpsCommPol.CommRsKeyRing = types.SetNull(commHttps.CommRsKeyRing.ElementType(ctx)) + // } + // } } } } - if CommHttpsCommPol.ThrottleRate.IsUnknown() { - CommHttpsCommPol.ThrottleRate = types.StringNull() - } - if CommHttpsCommPol.ThrottleSt.IsUnknown() { - CommHttpsCommPol.ThrottleSt = types.StringNull() - } - if CommHttpsCommPol.VisoreAccess.IsUnknown() { - CommHttpsCommPol.VisoreAccess = types.StringNull() + + // CommRsClientCertCAObject,diag:=types.SetValueFrom(ctx,types.StringType,CommRsClientCertCACommHttpsList) + // CommHttpsCommPol.CommRsClientCertCA=CommRsClientCertCAObject + //log.Printf("HERE from set %v %v",CommHttpsCommPol.CommRsClientCertCA, diag) + log.Printf("here CA outside %v %v %v",CommRsClientCertCAObject,CommRsClientCertCAObject.IsNull(),CommRsClientCertCAObject.IsUnknown()) + if !CommRsClientCertCAObject.IsNull(){ + log.Printf("here CA inside %v %v %v",CommRsClientCertCAObject,CommRsClientCertCAObject.IsNull(),CommRsClientCertCAObject.IsUnknown()) + CommHttpsCommPol.CommRsClientCertCA,_=types.SetValue(CommRsClientCertCAObject.Type(ctx),[]attr.Value{CommRsClientCertCAObject}) + } else{ + log.Printf("here CA else %v %v %v",CommRsClientCertCAObject,CommRsClientCertCAObject.IsNull(),CommRsClientCertCAObject.IsUnknown()) + CommHttpsCommPol.CommRsClientCertCA=types.SetNull(CommRsClientCertCAObject.Type(ctx)) } + // if !areAllStringFieldsEmpty(*CommRsClientCertCACommHttps) { + // CommHttpsCommPol.CommRsClientCertCA,_=types.SetValue(CommRsClientCertCAObject.Type(ctx),[]attr.Value{CommRsClientCertCAObject}) + // log.Printf("here ca0 %v",CommHttpsCommPol.CommRsClientCertCA) + // } else{ + // CommHttpsCommPol.CommRsClientCertCA=types.SetNull(CommRsClientCertCAObject.Type(ctx)) + // log.Printf("here ca1 %v",CommHttpsCommPol.CommRsClientCertCA) + // } + CommRsKeyRingObject, _ := types.ObjectValueFrom(ctx, CommRsKeyRingCommHttps.AttributeTypes(), CommRsKeyRingCommHttpsList[0]) + CommHttpsCommPol.CommRsKeyRing,_=types.SetValue(CommRsKeyRingObject.Type(ctx),[]attr.Value{CommRsKeyRingObject}) + // if !areAllStringFieldsEmpty(*CommRsKeyRingCommHttps) { + // CommHttpsCommPol.CommRsKeyRing,_=types.SetValue(CommRsKeyRingObject.Type(ctx),[]attr.Value{CommRsKeyRingObject}) + // log.Printf("here kr0 %v",CommHttpsCommPol.CommRsKeyRing) + // } else{ + // CommHttpsCommPol.CommRsKeyRing=types.SetNull(CommRsKeyRingObject.Type(ctx)) + // log.Printf("here kr1 %v",CommHttpsCommPol.CommRsKeyRing) + // } + + + + // if CommHttpsCommPol.CommRsClientCertCA.IsUnknown() || CommHttpsCommPol.CommRsClientCertCA.IsNull() { + // log.Printf("HERE in") + // log.Printf("HERE CertCA %v %v %v",CommHttpsCommPol.CommRsClientCertCA,CommHttpsCommPol.CommRsClientCertCA.IsUnknown(), CommHttpsCommPol.CommRsClientCertCA.IsNull()) + // CommHttpsCommPol.CommRsClientCertCA = basetypes.NewSetNull(CommRsKeyRingObject.Type(ctx)) + // } + //log.Printf("HERE CertCA %v %v",CommHttpsCommPol.CommRsClientCertCA, CommRsClientCertCAObject) + //log.Printf("HERE KeyRIng %v %v",CommHttpsCommPol.CommRsKeyRing,CommRsKeyRingObject) + // if CommHttpsCommPol.AccessControlAllowCredential.IsUnknown() { + // CommHttpsCommPol.AccessControlAllowCredential = types.StringNull(), + // } + // if CommHttpsCommPol.AccessControlAllowOrigins.IsUnknown() { + // CommHttpsCommPol.AccessControlAllowOrigins = types.StringNull(), + // } + // if CommHttpsCommPol.AdminSt.IsUnknown() { + // CommHttpsCommPol.AdminSt = types.StringNull(), + // } + // if CommHttpsCommPol.Annotation.IsUnknown() { + // CommHttpsCommPol.Annotation = types.StringNull(), + // } + // if CommHttpsCommPol.CliOnlyMode.IsUnknown() { + // CommHttpsCommPol.CliOnlyMode = types.StringNull(), + // } + // if CommHttpsCommPol.ClientCertAuthState.IsUnknown() { + // CommHttpsCommPol.ClientCertAuthState = types.StringNull(), + // } + // if CommHttpsCommPol.Descr.IsUnknown() { + // CommHttpsCommPol.Descr = types.StringNull(), + // } + // if CommHttpsCommPol.DhParam.IsUnknown() { + // CommHttpsCommPol.DhParam = types.StringNull(), + // } + // if CommHttpsCommPol.GlobalThrottleRate.IsUnknown() { + // CommHttpsCommPol.GlobalThrottleRate = types.StringNull(), + // } + // if CommHttpsCommPol.GlobalThrottleSt.IsUnknown() { + // CommHttpsCommPol.GlobalThrottleSt = types.StringNull(), + // } + // if CommHttpsCommPol.GlobalThrottleUnit.IsUnknown() { + // CommHttpsCommPol.GlobalThrottleUnit = types.StringNull(), + // } + // if CommHttpsCommPol.MaxRequestStatusCount.IsUnknown() { + // CommHttpsCommPol.MaxRequestStatusCount = types.StringNull(), + // } + // if CommHttpsCommPol.Name.IsUnknown() { + // CommHttpsCommPol.Name = types.StringNull(), + // } + // if CommHttpsCommPol.NameAlias.IsUnknown() { + // CommHttpsCommPol.NameAlias = types.StringNull(), + // } + // if CommHttpsCommPol.NodeExporter.IsUnknown() { + // CommHttpsCommPol.NodeExporter = types.StringNull(), + // } + // if CommHttpsCommPol.Referer.IsNull() { + // CommHttpsCommPol.Referer = types.StringNull(), + // } + // if CommHttpsCommPol.ServerHeader.IsUnknown() { + // CommHttpsCommPol.ServerHeader = types.StringNull(), + // } + // if CommHttpsCommPol.SslProtocols.IsUnknown() { + // var datasslProtocolsCommHttpsCommPol []CommHttpsCommPolResourceModel + // data.CommHttps.ElementsAs(ctx, &datasslProtocolsCommHttpsCommPol, false) + // for _, commHttps := range datasslProtocolsCommHttpsCommPol { + // if CommHttpsCommPol.SslProtocols.IsUnknown() { + // CommHttpsCommPol.SslProtocols = types.SetNull(commHttps.SslProtocols.ElementType(ctx)) + // } + // } + // } + // if CommHttpsCommPol.ThrottleRate.IsUnknown() { + // CommHttpsCommPol.ThrottleRate = types.StringNull(), + // } + // if CommHttpsCommPol.ThrottleSt.IsUnknown() { + // CommHttpsCommPol.ThrottleSt = types.StringNull(), + // } + // if CommHttpsCommPol.VisoreAccess.IsUnknown() { + // CommHttpsCommPol.VisoreAccess = types.StringNull(), + // } CommHttpsCommPolList[0] = CommHttpsCommPol } if childClassName == "tagAnnotation" { @@ -1066,8 +1253,13 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl } } if len(CommHttpsCommPolList) > 0 { - commHttpsSet, _ := types.SetValueFrom(ctx, data.CommHttps.ElementType(ctx), CommHttpsCommPolList) - data.CommHttps = commHttpsSet + commHttpsSet, _ := types.SetValueFrom(ctx, data.CommHttps.ElementType(ctx),CommHttpsCommPolList) + data.CommHttps=commHttpsSet + // commHttpsSet, diags := types.ObjectValueFrom(ctx, CommHttpsCommPol.AttributeTypes(), CommHttpsCommPolList[0]) + log.Printf("HERE %v %v %v",CommHttpsCommPolList,commHttpsSet, diags) + + // data.CommHttps = types.SetValueMust(commHttpsSet.Type(ctx),[]attr.Value{commHttpsSet}) + log.Printf("HERE %v %v %v",commHttpsSet,data.CommHttps,diags) } if len(TagAnnotationCommPolList) > 0 { tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationCommPolList) @@ -1112,6 +1304,15 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti Attributes: make(map[string]interface{}), Children: make([]map[string]interface{}, 0), } + CommHttpsChildren := make([]map[string]interface{}, 0) + commRsClientCertCAChildMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } + commRsKeyRingChildMap := childMapType{ + Attributes: make(map[string]interface{}), + Children: make([]map[string]interface{}, 0), + } childPayloads := []map[string]interface{}{} if !data.CommHttps.IsUnknown() { for _, commHttps := range commHttpsPlan { @@ -1185,7 +1386,6 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti if !commHttps.VisoreAccess.IsUnknown() { childMap.Attributes["visoreAccess"] = commHttps.VisoreAccess.ValueString() } - CommHttpsChildren := make([]map[string]interface{}, 0) var commRsClientCertCAPlan, commRsClientCertCAState []CommRsClientCertCACommHttpsResourceModel for i, commHttps := range commHttpsPlan { commHttps.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCAPlan, false) @@ -1196,18 +1396,11 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti commHttpsState[i].CommRsClientCertCA, _ = types.SetValueFrom(ctx, commHttps.CommRsClientCertCA.ElementType(ctx), commRsClientCertCAState) } if len(commRsClientCertCAPlan) == 0 && len(commRsClientCertCAState) == 1 { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childPayloads = append(childPayloads, map[string]interface{}{"commRsClientCertCA": childMap}) + commRsClientCertCAChildMap.Attributes["status"] = "deleted" + CommHttpsChildren = append(CommHttpsChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCAChildMap}) } if !commHttps.CommRsClientCertCA.IsUnknown() { for _, commRsClientCertCA := range commRsClientCertCAPlan { - commRsClientCertCAChildMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } if !commRsClientCertCA.Annotation.IsUnknown() { commRsClientCertCAChildMap.Attributes["annotation"] = commRsClientCertCA.Annotation.ValueString() } else { @@ -1219,7 +1412,7 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti CommHttpsChildren = append(CommHttpsChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCAChildMap}) } } - childMap.Children = CommHttpsChildren + //childMap.Children = CommHttpsChildren var commRsKeyRingPlan, commRsKeyRingState []CommRsKeyRingCommHttpsResourceModel for i, commHttps := range commHttpsPlan { commHttps.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingPlan, false) @@ -1238,10 +1431,6 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti } if !commHttps.CommRsKeyRing.IsUnknown() { for _, commRsKeyRing := range commRsKeyRingPlan { - commRsKeyRingChildMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } if !commRsKeyRing.Annotation.IsUnknown() { commRsKeyRingChildMap.Attributes["annotation"] = commRsKeyRing.Annotation.ValueString() } else { diff --git a/internal/provider/utils.go b/internal/provider/utils.go index 168a2ba2d..273029609 100644 --- a/internal/provider/utils.go +++ b/internal/provider/utils.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "net/http" + "reflect" "strings" "github.com/ciscoecosystem/aci-go-client/v2/client" @@ -13,6 +14,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-log/tflog" ) @@ -130,6 +132,29 @@ func (m setToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate) PlanModifyStrin return } +// type setToUnknownWhenStateIsNullPlanIsUnknownDuringUpdate struct{} + +// func SetToUnknownWhenStateIsNullPlanIsUnknownDuringUpdate() planmodifier.String { +// return setToUnknownWhenStateIsNullPlanIsUnknownDuringUpdate{} +// } + +// func (m setToUnknownWhenStateIsNullPlanIsUnknownDuringUpdate) Description(_ context.Context) string { +// return "During the update phase, set the value of this attribute to StringNull when the state value is null and the plan value is unknown." +// } + +// func (m setToUnknownWhenStateIsNullPlanIsUnknownDuringUpdate) MarkdownDescription(_ context.Context) string { +// return "During the update phase, set the value of this attribute to StringNull when the state value is null and the plan value is unknown." +// } + +// // Custom plan modifier to set the plan value to null under certain conditions +// func (m setToUnknownWhenStateIsNullPlanIsUnknownDuringUpdate) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { +// // Set the plan value to StringType null when state value is null and plan value is unknown during an Update +// if !req.State.Raw.IsNull() && req.StateValue.IsNull() && req.PlanValue.IsNull() { +// resp.PlanValue = types.StringUnknown() +// } +// return +// } + type setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate struct{} func SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate() planmodifier.Set { @@ -147,9 +172,50 @@ func (m setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate) MarkdownDescriptio // Custom plan modifier to set the plan value to null under certain conditions func (m setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate) PlanModifySet(ctx context.Context, req planmodifier.SetRequest, resp *planmodifier.SetResponse) { // Set the plan value to SetType null when state value is null and plan value is unknown during an Update - log.Printf("heretstaeval %v;herestate unknown %v; herestate null %v;hereplanval %v, hereplan unknown %v, hereplan null %v", req.StateValue, req.StateValue.IsUnknown(), req.StateValue.IsNull(), req.PlanValue, req.PlanValue.IsUnknown(), req.PlanValue.IsNull()) - if !req.State.Raw.IsNull() && req.StateValue.IsNull() && req.PlanValue.IsUnknown() { - resp.PlanValue = types.SetNull(req.PlanValue.ElementType(ctx)) - } + log.Printf("hereStateval %v", req.StateValue) + log.Printf("hereStatevalIsUnknown %v", req.StateValue.IsUnknown()) + log.Printf("hereStatevalIsNull %v", req.StateValue.IsNull()) + log.Printf("herePlanval %v", req.PlanValue) + log.Printf("herePlanvalIsUnknown %v", req.PlanValue.IsUnknown()) + log.Printf("herePlanvalIsNull %v", req.PlanValue.IsNull()) + + // log.Printf("hereType %v %v", idx, element.Type(ctx)) + // } + // if !req.State.Raw.IsNull() && req.PlanValue.Equal(req.StateValue) && req.ConfigValue.IsNull(){ + // resp.PlanValue = types.SetNull(req.PlanValue.ElementType(ctx)) + // } + + // if !req.State.Raw.IsNull() && req.StateValue.IsNull() && req.PlanValue.IsUnknown() { + // //log.Printf("hereStateval %v;hereStateIsUnknown %v; hereStateIsNull %v;herePlanVal %v, herePlanIsUnknown %v, herePlanIsNull %v, hereConfigVal %v, hereConfisIsUnkown %v, hereConfigIsNull %v", req.StateValue, req.StateValue.IsUnknown(), req.StateValue.IsNull(), req.PlanValue, req.PlanValue.IsUnknown(), req.PlanValue.IsNull(), req.ConfigValue, req.ConfigValue.IsUnknown(), req.ConfigValue.IsNull()) + // resp.PlanValue = types.SetNull(req.PlanValue.ElementType(ctx)) + // } return } + +func areAllStringFieldsEmpty(v interface{}) bool { + val := reflect.ValueOf(v) + + // Check if the passed interface is a struct + if val.Kind() != reflect.Struct { + return false + } + + // Iterate over all fields in the struct + for i := 0; i < val.NumField(); i++ { + field := val.Field(i) + fieldType := field.Type() + + // Check if the field is of type basestring + if fieldType != reflect.TypeOf(basetypes.NewStringValue("")) { + return false + } + + // Check if the string is not empty + if !field.IsZero() { + return false + } + } + + // All string fields are empty + return true +} From b00662156db994b7ff72a2f6e8208f0561bf06d5 Mon Sep 17 00:00:00 2001 From: Shreyas Date: Tue, 16 Apr 2024 19:37:14 -0400 Subject: [PATCH 05/20] [ignore] Made changes to resource for testing custom function for element type of a grand child object --- .../resource_aci_communication_policy.go | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/internal/provider/resource_aci_communication_policy.go b/internal/provider/resource_aci_communication_policy.go index b760b908a..251ad4261 100644 --- a/internal/provider/resource_aci_communication_policy.go +++ b/internal/provider/resource_aci_communication_policy.go @@ -159,6 +159,10 @@ func CommRsClientCertCACommHttpsResourceModelAttributeTypes() map[string]attr.Ty } } +func CommRsClientCertCACommHttpsResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{},CommRsClientCertCACommHttpsResourceModelAttributeTypes()) +} + func NewCommRsClientCertCACommHttpsResourceModel() *CommRsClientCertCACommHttpsResourceModel { return &CommRsClientCertCACommHttpsResourceModel{ Annotation: types.StringNull(), @@ -186,6 +190,7 @@ func NewCommRsKeyRingCommHttpsResourceModel() *CommRsKeyRingCommHttpsResourceMod } } + // TagAnnotationCommPolResourceModel describes the resource data model for the children without relation ships. type TagAnnotationCommPolResourceModel struct { Key types.String `tfsdk:"key"` @@ -905,10 +910,10 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl } CommHttpsCommPolList := make([]CommHttpsCommPolResourceModel, 1) var CommHttpsCommPol CommHttpsCommPolResourceModel - //CommRsClientCertCACommHttpsList := make([]CommRsClientCertCACommHttpsResourceModel, 1) + CommRsClientCertCACommHttpsList := make([]CommRsClientCertCACommHttpsResourceModel, 0) //var CommRsClientCertCACommHttps2 CommRsClientCertCACommHttpsResourceModel //var CommRsClientCertCAObject basetypes.ObjectValue - CommRsClientCertCAObject:=types.ObjectNull(CommRsClientCertCACommHttpsResourceModelAttributeTypes()) + //CommRsClientCertCAObject:=types.ObjectNull(CommRsClientCertCACommHttpsResourceModelAttributeTypes()) CommRsKeyRingCommHttpsList := make([]CommRsKeyRingCommHttpsResourceModel, 1) var CommRsKeyRingCommHttps CommRsKeyRingCommHttpsResourceModel TagAnnotationCommPolList := make([]TagAnnotationCommPolResourceModel, 0) @@ -1052,7 +1057,8 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl CommRsClientCertCACommHttps.TDn = basetypes.NewStringValue(tDn) } - CommRsClientCertCAObject, _ = types.ObjectValueFrom(ctx, CommRsClientCertCACommHttpsResourceModelAttributeTypes(), CommRsClientCertCACommHttps) + //CommRsClientCertCAObject, _ = types.ObjectValueFrom(ctx, CommRsClientCertCACommHttpsResourceModelAttributeTypes(), CommRsClientCertCACommHttps) + CommRsClientCertCACommHttpsList = append(CommRsClientCertCACommHttpsList, CommRsClientCertCACommHttps) } @@ -1108,14 +1114,21 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl // CommRsClientCertCAObject,diag:=types.SetValueFrom(ctx,types.StringType,CommRsClientCertCACommHttpsList) // CommHttpsCommPol.CommRsClientCertCA=CommRsClientCertCAObject //log.Printf("HERE from set %v %v",CommHttpsCommPol.CommRsClientCertCA, diag) - log.Printf("here CA outside %v %v %v",CommRsClientCertCAObject,CommRsClientCertCAObject.IsNull(),CommRsClientCertCAObject.IsUnknown()) - if !CommRsClientCertCAObject.IsNull(){ - log.Printf("here CA inside %v %v %v",CommRsClientCertCAObject,CommRsClientCertCAObject.IsNull(),CommRsClientCertCAObject.IsUnknown()) - CommHttpsCommPol.CommRsClientCertCA,_=types.SetValue(CommRsClientCertCAObject.Type(ctx),[]attr.Value{CommRsClientCertCAObject}) + //basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{},CommRsClientCertCACommHttpsResourceModelAttributeTypes()) + if len(CommRsClientCertCACommHttpsList) > 0 { + CommRsClientCertCASet,_:=types.SetValueFrom(ctx,CommRsClientCertCACommHttpsResourceModelElementType(),CommRsClientCertCACommHttpsList) + CommHttpsCommPol.CommRsClientCertCA=CommRsClientCertCASet } else{ - log.Printf("here CA else %v %v %v",CommRsClientCertCAObject,CommRsClientCertCAObject.IsNull(),CommRsClientCertCAObject.IsUnknown()) - CommHttpsCommPol.CommRsClientCertCA=types.SetNull(CommRsClientCertCAObject.Type(ctx)) + CommHttpsCommPol.CommRsClientCertCA=types.SetNull(CommRsClientCertCACommHttpsResourceModelElementType()) } + // log.Printf("here CA WithAttr %v",CommRsClientCertCACommHttpsResourceModelElementType()) + // if !CommRsClientCertCAObject.IsNull(){ + // log.Printf("here CA inside %v %v %v",CommRsClientCertCAObject,CommRsClientCertCAObject.IsNull(),CommRsClientCertCAObject.IsUnknown()) + // CommHttpsCommPol.CommRsClientCertCA,_=types.SetValue(CommRsClientCertCAObject.Type(ctx),[]attr.Value{CommRsClientCertCAObject}) + // } else{ + // log.Printf("here CA else %v %v %v",CommRsClientCertCAObject,CommRsClientCertCAObject.IsNull(),CommRsClientCertCAObject.IsUnknown()) + // CommHttpsCommPol.CommRsClientCertCA=types.SetNull(CommRsClientCertCAObject.Type(ctx)) + // } // if !areAllStringFieldsEmpty(*CommRsClientCertCACommHttps) { // CommHttpsCommPol.CommRsClientCertCA,_=types.SetValue(CommRsClientCertCAObject.Type(ctx),[]attr.Value{CommRsClientCertCAObject}) // log.Printf("here ca0 %v",CommHttpsCommPol.CommRsClientCertCA) @@ -1262,6 +1275,7 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl log.Printf("HERE %v %v %v",commHttpsSet,data.CommHttps,diags) } if len(TagAnnotationCommPolList) > 0 { + log.Printf("HERE TAG %v",data.TagAnnotation.ElementType(ctx)) tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationCommPolList) data.TagAnnotation = tagAnnotationSet } From 5d0881a2aa190ddb6477910f85de823a44baa4f9 Mon Sep 17 00:00:00 2001 From: Shreyas Date: Thu, 18 Apr 2024 16:40:16 -0400 Subject: [PATCH 06/20] [ignore] Made changes to resource template to accommodate rsp sub tree filter with grand child classes --- gen/generator.go | 1 + gen/templates/resource.go.tmpl | 293 +++++----- .../resource_aci_communication_policy.go | 549 +++++------------- .../provider/resource_aci_endpoint_tag_ip.go | 81 ++- .../provider/resource_aci_endpoint_tag_mac.go | 81 ++- ...nal_management_network_instance_profile.go | 124 ++-- ..._aci_external_management_network_subnet.go | 81 ++- .../resource_aci_l3out_consumer_label.go | 81 ++- .../resource_aci_l3out_redistribute_policy.go | 81 ++- .../resource_aci_out_of_band_contract.go | 81 ++- .../resource_aci_pim_route_map_entry.go | 81 ++- .../resource_aci_pim_route_map_policy.go | 81 ++- ...lation_to_consumed_out_of_band_contract.go | 81 ++- internal/provider/utils.go | 103 +--- 14 files changed, 679 insertions(+), 1120 deletions(-) diff --git a/gen/generator.go b/gen/generator.go index 18d210c67..0f77992a3 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -103,6 +103,7 @@ var templateFuncs = template.FuncMap{ "getTestConfigVariableName": GetTestConfigVariableName, "getDevnetDocForClass": GetDevnetDocForClass, "lowerFirstCharacter": LowerFirstCharacter, + "isListEmpty": func(stringList []string) bool { return len(stringList) == 0 }, } // Global variables used for unique resource name setting based on label from meta data diff --git a/gen/templates/resource.go.tmpl b/gen/templates/resource.go.tmpl index 864e42f42..d7cba76db 100644 --- a/gen/templates/resource.go.tmpl +++ b/gen/templates/resource.go.tmpl @@ -31,6 +31,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" {{- if or .HasChild .HasBitmask}} + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" {{- end}} "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" @@ -77,7 +78,7 @@ type {{.ResourceClassName}}ResourceModel struct { {{- range .Children}} -{{- template "childStructs" . }} +{{- template "childStructsAndAttributeTypes" . }} {{- end}} @@ -135,7 +136,6 @@ func (r *{{.ResourceClassName}}Resource) Schema(ctx context.Context, req resourc Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, {{- if .ValidValues}} Validators: []validator.Set{ @@ -384,7 +384,7 @@ func (r *{{.ResourceClassName}}Resource) ImportState(ctx context.Context, req re func getAndSet{{.ResourceClassName}}Attributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *{{.ResourceClassName}}ResourceModel) { {{- if .HasChild}} - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "{{- .PkgName}},{{ template "rspSubtreeClassFilter" . }}"), "GET", nil) {{- else}} requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) {{- end}} @@ -449,7 +449,7 @@ func getAndSet{{.ResourceClassName}}Attributes(ctx context.Context, diags *diag. {{- if .HasChild}} {{- range .Children}} - {{- template "declareChildLists" . }} + {{- template "declareChildListsInGetandSetAttributesFunction" . }} {{- end}} _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -459,7 +459,6 @@ func getAndSet{{.ResourceClassName}}Attributes(ctx context.Context, diags *diag. childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) {{- range .Children}} if childClassName == "{{ .PkgName }}" { - {{.ResourceClassName}}{{$.ResourceClassName}} := {{ .ResourceClassName}}{{$.ResourceClassName}}ResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { {{- range .Properties}} {{- if eq .ValueType "bitmask"}} @@ -479,12 +478,9 @@ func getAndSet{{.ResourceClassName}}Attributes(ctx context.Context, diags *diag. {{- else}} if childAttributeName == "{{.PropertyName}}" { {{.PropertyName}}List := strings.Split(childAttributeValue.(string), ",") - var data{{.ResourceClassName}}{{$.ResourceClassName}} []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel - data.{{.ResourceClassName}}.ElementsAs(ctx,&data{{.ResourceClassName}}{{$.ResourceClassName}},false) - for _, {{.ResourceClassName | lowerFirstCharacter}} := range data{{.ResourceClassName}}{{$.ResourceClassName}} { - {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, {{.ResourceClassName | lowerFirstCharacter}}.{{.Name}}.ElementType(ctx),{{.PropertyName}}List) + {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, basetypes.StringType{},{{.PropertyName}}List) {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}} = {{.PropertyName}}Set - } + } {{- end}} {{- else}} @@ -501,48 +497,39 @@ func getAndSet{{.ResourceClassName}}Attributes(ctx context.Context, diags *diag. {{- end}} {{- end}} {{- end}} - {{- $parentLevel := .ResourceClassName }} - {{- $parentLevelCloseBracket := .ResourceClassName }} + {{/* $enteredGrandChildGetAndSetAttributesZone is used here because the presence of grand children is unknown while rendering the template unlike .HasChild used for the immediate children. It is also used because there can be more than one grandchild in the same level*/}} + {{- $enteredGrandChildGetAndSetAttributesZone := false }} {{- range .Children}} - {{- if eq $parentLevel .ParentName }} - {{- $parentLevel = .ResourceClassName }} - childClasses{{.ParentName}} := childClassDetails.(map[string]interface{})["children"].([]interface{}) - for _, child{{.ParentName}} := range childClasses{{.ParentName}} { - for childClassName{{.ParentName}}, childClassDetails{{.ParentName}} := range child{{.ParentName}}.(map[string]interface{}) { - {{- end}} - if childClassName{{.ParentName}} == "{{.PkgName}}" { + {{- if not $enteredGrandChildGetAndSetAttributesZone }} + {{- $enteredGrandChildGetAndSetAttributesZone = true }} + } + _, childrenOf{{.ParentName}}Exist:= childClassDetails.(map[string]interface{})["children"] + if childrenOf{{.ParentName}}Exist { + childClassesOf{{.ParentName}} := childClassDetails.(map[string]interface{})["children"].([]interface{}) + for _, child{{.ParentName}} := range childClassesOf{{.ParentName}} { + for childClassName{{.ParentName}}, childClassDetails{{.ParentName}} := range child{{.ParentName}}.(map[string]interface{}) { + {{- end}} {{- template "getAndSetGrandChildren" . }} - {{- if eq $parentLevelCloseBracket .ParentName }} - {{- $parentLevelCloseBracket = .ResourceClassName }} - {{- else}} - } - } - {{- end }} {{- end }} + {{- if $enteredGrandChildGetAndSetAttributesZone }} + } + } } - {{- range .Properties}} - if {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}}.IsUnknown() { - {{- if eq .ValueType "bitmask"}} - var data{{.PropertyName}}{{.ResourceClassName}}{{$.ResourceClassName}} []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel - data.{{.ResourceClassName}}.ElementsAs(ctx,&data{{.PropertyName}}{{.ResourceClassName}}{{$.ResourceClassName}},false) - for _, {{.ResourceClassName | lowerFirstCharacter}} := range data{{.PropertyName}}{{.ResourceClassName}}{{$.ResourceClassName}} { - if {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}}.IsUnknown(){ - {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}} = types.SetNull({{.ResourceClassName | lowerFirstCharacter}}.{{.Name}}.ElementType(ctx)) - } + {{- range .Children}} + if len({{.ResourceClassName}}{{.ParentName}}List) > 0 { + {{.ResourceClassName}}Set,_:=types.SetValueFrom(ctx,{{.ResourceClassName}}{{.ParentName}}ResourceModelElementType(),{{.ResourceClassName}}{{.ParentName}}List) + {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}}={{.ResourceClassName}}Set + } else{ + {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}}=types.SetNull({{.ResourceClassName}}{{.ParentName}}ResourceModelElementType()) + } + {{- end}} + {{- else}} } - {{- else}} - {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}} = types.StringNull() - {{- end}} + {{- end}} + {{.ResourceClassName}}{{$.ResourceClassName}}List = append({{.ResourceClassName}}{{$.ResourceClassName}}List,{{.ResourceClassName}}{{$.ResourceClassName}}) } - {{- end}} - {{- if .IdentifiedBy}} - {{.ResourceClassName}}{{$.ResourceClassName}}List = append({{.ResourceClassName}}{{$.ResourceClassName}}List, {{.ResourceClassName}}{{$.ResourceClassName}}) - {{- else}} - {{.ResourceClassName}}{{$.ResourceClassName}}List[0] = {{.ResourceClassName}}{{$.ResourceClassName}} - {{- end}} - } {{- end}} - } + } } } {{- range .Children}} @@ -611,16 +598,20 @@ func set{{.ResourceClassName}}Id(ctx context.Context, data *{{.ResourceClassName {{ range .Children}} func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *{{$.ResourceClassName}}ResourceModel, {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel) []map[string]interface{} { -type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } -childPayloads := []map[string]interface{}{} -if !data.{{.ResourceClassName}}.IsUnknown() { + childMap := newAciObjectType() + childPayloads := []map[string]interface{}{} + {{- $enteredGrandChildDeclarationZone := false }} + {{- range .Children}} + {{- $enteredGrandChildDeclarationZone = true }} + {{- template "grandChildDeclarationInChildPayloadFunction" . }} + {{- end}} + {{- range .Children}} + {{- if $enteredGrandChildDeclarationZone }} + {{- $enteredGrandChildDeclarationZone = false }} + {{.ParentName}}Children := make([]map[string]interface{}, 0) + {{- end}} + {{- end}} + if !data.{{.ResourceClassName}}.IsUnknown() { {{- if .IdentifiedBy}} {{ .PkgName }}Identifiers := []{{.ResourceClassName}}Identifier{} {{- end}} @@ -640,18 +631,19 @@ if !data.{{.ResourceClassName}}.IsUnknown() { childMap.Attributes["annotation"] = globalAnnotation } {{- end}} {{- end}} - {{- $parentLevel := .ParentName }} + {{- $enteredGrandChildPayloadZone := false }} {{- range .Children}} - {{- if ne $parentLevel .ParentName }} - {{- $parentLevel = .ParentName }} - {{.ParentName}}Children := make([]map[string]interface{}, 0) - {{- end}} - {{- template "grandChildPayloads" . }} - } - childMap.Children = {{ .ParentName }}Children + {{- $enteredGrandChildPayloadZone = true }} + {{- template "grandChildPayload" . }} {{- end}} -childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": childMap}) -{{- if .IdentifiedBy}} + {{- range .Children}} + {{- if $enteredGrandChildPayloadZone }} + {{- $enteredGrandChildPayloadZone = false }} + childMap.Children = {{.ParentName}}Children + {{- end}} + {{- end}} + childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": childMap}) + {{- if .IdentifiedBy}} {{ .PkgName }}Identifier := {{ .ResourceClassName }}Identifier{} {{- range .Properties}} {{- if .IsNaming}} @@ -676,26 +668,22 @@ childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": c } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" + {{.PkgName}}ChildMapForDelete := newAciObjectType() + {{.PkgName}}ChildMapForDelete.Attributes["status"] = "deleted" {{- range .Properties}} {{- if .IsNaming }} - childMap.Attributes["{{.PropertyName}}"] = {{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.ValueString() + {{.PkgName}}ChildMapForDelete.Attributes["{{.PropertyName}}"] = {{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.ValueString() {{- end}} {{- end}} - childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": childMap}) + childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": {{.PkgName}}ChildMapForDelete}) } } {{- else}} if len({{ .PkgName }}Plan) == 0 && len({{ .PkgName }}State) == 1 { {{- if .AllowDelete}} - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": childMap}) + {{.PkgName}}ChildMapForDelete := newAciObjectType() + {{.PkgName}}ChildMapForDelete.Attributes["status"] = "deleted" + childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": {{.PkgName}}ChildMapForDelete}) {{- else}} diags.AddError( "{{ .ResourceClassName }} object cannot be deleted", @@ -765,7 +753,7 @@ func get{{.ResourceClassName}}CreateJsonPayload(ctx context.Context, diags *diag } {{/* A sub template for the child structs used in the structs definiton section. */}} -{{- define "childStructs" }} +{{- define "childStructsAndAttributeTypes" }} // {{.ResourceClassName}}{{.ParentName}}ResourceModel describes the resource data model for the children without relation ships. type {{.ResourceClassName}}{{.ParentName}}ResourceModel struct { {{- range .Properties}} @@ -781,8 +769,27 @@ type {{.ResourceClassName}}{{.ParentName}}ResourceModel struct { {{ .ResourceClassName }} types.Set `tfsdk:"{{- .ResourceName}}"` {{- end}} } +func {{.ResourceClassName}}{{.ParentName}}ResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + {{- range .Properties}} + {{- if eq .ValueType "bitmask"}} + "{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}": types.SetType{ElemType: types.StringType}, + {{- else if eq .Name "Id"}} + "{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}": types.StringType, + {{- else}} + "{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}": types.StringType, + {{- end}} + {{- end}} + {{- range .Children}} + "{{ .ResourceName }}": types.SetType{ElemType: types.StringType}, + {{- end}} + } +} +func {{.ResourceClassName}}{{.ParentName}}ResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{},{{.ResourceClassName}}{{.ParentName}}ResourceModelAttributeTypes()) +} {{- range .Children}} -{{- template "childStructs" . }} +{{- template "childStructsAndAttributeTypes" . }} {{- end}} {{- end}} @@ -794,7 +801,6 @@ type {{.ResourceClassName}}{{.ParentName}}ResourceModel struct { Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, {{- if not .IdentifiedBy }} Validators: []validator.Set{ @@ -811,7 +817,6 @@ type {{.ResourceClassName}}{{.ParentName}}ResourceModel struct { Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, {{- if .ValidValues }} Validators: []validator.Set{ @@ -853,23 +858,15 @@ type {{.ResourceClassName}}{{.ParentName}}ResourceModel struct { {{- end }} {{/* A sub template for the grand child attributes used in the Payload function. */}} -{{- define "grandChildPayloads" }} -var {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{.ParentName}}ResourceModel -for i, {{.ParentName | lowerFirstCharacter}} := range {{.ParentName | lowerFirstCharacter}}Plan { +{{- define "grandChildPayload" }} +var {{.PkgName}}Plan []{{.ResourceClassName}}{{.ParentName}}ResourceModel {{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}Plan, false) -{{ .ParentName | lowerFirstCharacter}}Plan[i].{{.ResourceClassName}},_ = types.SetValueFrom(ctx,{{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementType(ctx),{{.PkgName}}Plan) -} -for i, {{.ParentName | lowerFirstCharacter}} := range {{.ParentName | lowerFirstCharacter}}State { - {{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}State, false) - {{ .ParentName | lowerFirstCharacter}}State[i].{{.ResourceClassName}},_ = types.SetValueFrom(ctx,{{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementType(ctx),{{.PkgName}}State) -} -if len({{ .PkgName }}Plan) == 0 && len({{ .PkgName }}State) == 1 { +for _, {{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}} := range {{.ParentName | lowerFirstCharacter}}State { +if len({{ .PkgName }}Plan) == 0 && len({{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}}.{{.ResourceClassName}}.Elements()) == 1 { {{- if .AllowDelete}} - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": childMap}) + {{.PkgName}}ChildMap := newAciObjectType() + {{.PkgName}}ChildMap.Attributes["status"] = "deleted" + {{ .ParentName }}Children = append({{ .ParentName }}Children, map[string]interface{}{"{{.PkgName}}": {{.PkgName}}ChildMap}) {{- else}} diags.AddError( "{{ .ResourceClassName }} object cannot be deleted", @@ -878,12 +875,9 @@ if len({{ .PkgName }}Plan) == 0 && len({{ .PkgName }}State) == 1 { return nil {{- end }} } +} if !{{ .ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.IsUnknown(){ - for _, {{ .PkgName }} := range {{.PkgName}}Plan { - {{.PkgName}}ChildMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } +for _, {{ .PkgName }} := range {{.PkgName}}Plan { {{- range .Properties}} if !{{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsUnknown(){ {{- if eq .ValueType "bitmask"}} @@ -899,34 +893,31 @@ if !{{ .ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.IsUnknown(){ {{.PkgName}}ChildMap.Attributes["annotation"] = globalAnnotation } {{- end}} {{- end}} - {{- $parentLevel := .ParentName }} {{- range .Children}} - {{- if ne $parentLevel .ParentName }} - {{- $parentLevel = .ParentName }} - {{.ParentName}}Children := make([]map[string]interface{}, 0) - {{- end}} - {{- template "grandChildPayloads" . }} + {{- template "grandChildPayload" . }} {{- end}} {{ .ParentName }}Children = append({{ .ParentName }}Children, map[string]interface{}{"{{.PkgName}}": {{.PkgName}}ChildMap}) } + } {{- end }} -{{- define "declareChildLists" }} +{{- define "declareChildListsInGetandSetAttributesFunction" }} +{{.ResourceClassName}}{{.ParentName}} := {{ .ResourceClassName}}{{.ParentName}}ResourceModel{} {{- if .IdentifiedBy}} {{ .ResourceClassName }}{{$.ParentName}}List := make([]{{.ResourceClassName}}{{$.ParentName}}ResourceModel, 0) {{- else}} -{{ .ResourceClassName }}{{$.ParentName}}List := make([]{{.ResourceClassName}}{{$.ParentName}}ResourceModel, 1) +{{ .ResourceClassName }}{{$.ParentName}}List := make([]{{.ResourceClassName}}{{$.ParentName}}ResourceModel, 0) {{- end}} {{- range .Children}} -{{- template "declareChildLists" . }} +{{- template "declareChildListsInGetandSetAttributesFunction" . }} {{- end}} {{- end}} {{- define "getAndSetGrandChildren" }} -{{.ResourceClassName}}{{.ParentName}} := {{ .ResourceClassName}}{{.ParentName}}ResourceModel{} +if childClassName{{.ParentName}} == "{{.PkgName}}"{ {{.PkgName}}childAttributeValue:= childClassDetails{{.ParentName}}.(map[string]interface{})["attributes"].(map[string]interface{}) for childAttributeName, childAttributeValue := range {{.PkgName}}childAttributeValue { {{- range .Properties}} @@ -969,48 +960,60 @@ for childAttributeName, childAttributeValue := range {{.PkgName}}childAttributeV {{- end}} {{- end}} {{- end}} - {{- $parentLevel := .ParentName }} + {{- $enteredGrandChildGetAndSetAttributesZone := false }} {{- range .Children}} - {{- if ne $parentLevel .ParentName }} - {{- $parentLevel = .ParentName }} - childClasses{{.ParentName}} := childClassDetails.(map[string]interface{})["children"].(map[string]interface{}) - for _, child{{.ParentName}} := range childClasses{{.ParentName}} { - for childClassName{{.ParentName}}, childClassDetails{{.ParentName}} := range child{{.ParentName}}.([]interface{}) { + {{- if not $enteredGrandChildGetAndSetAttributesZone }} + {{- $enteredGrandChildGetAndSetAttributesZone = true }} + } + _, childrenOf{{.ParentName}}:= childClassDetails.(map[string]interface{})["children"] + if childrenOf{{.ParentName}} { + childClassesOf{{.ParentName}} := childClassDetails.(map[string]interface{})["children"].([]interface{}) + for _, child{{.ParentName}} := range childClassesOf{{.ParentName}} { + for childClassName{{.ParentName}}, childClassDetails{{.ParentName}} := range child{{.ParentName}}.(map[string]interface{}) { {{- end}} - if childClassName{{.ParentName}} == "{{.PkgName}}" { {{- template "getAndSetGrandChildren" . }} + {{- end }} + {{- if $enteredGrandChildGetAndSetAttributesZone }} + } + } + } + {{- range .Children}} + if len({{.ResourceClassName}}{{.ParentName}}List) > 0 { + {{.ResourceClassName}}Set,_:=types.SetValueFrom(ctx,{{.ResourceClassName}}{{.ParentName}}ResourceModelElementType(),{{.ResourceClassName}}{{.ParentName}}List) + {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}}={{.ResourceClassName}}Set + } else{ + {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}}=types.SetNull({{.ResourceClassName}}{{.ParentName}}ResourceModelElementType()) } {{- end}} - {{- range .Properties}} - if {{.ResourceClassName}}{{$.ParentName}}.{{.Name}}.IsNull() { - {{- if eq .ValueType "bitmask"}} - var data{{.PropertyName}}{{.ResourceClassName}}{{$.ResourceClassName}} []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel - data.{{.ResourceClassName}}.ElementsAs(ctx,&data{{.PropertyName}}{{.ResourceClassName}}{{$.ResourceClassName}},false) - for _, {{.ResourceClassName | lowerFirstCharacter}} := range data{{.PropertyName}}{{.ResourceClassName}}{{$.ResourceClassName}} { - if {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}}.IsNull(){ - {{.ResourceClassName}}{{$.ResourceClassName}}.{{.Name}} = types.SetUnknown({{.ResourceClassName | lowerFirstCharacter}}.{{.Name}}.ElementType(ctx)) - } - } {{- else}} - {{.ResourceClassName}}{{$.ParentName}}.{{.Name}} = types.StringUnknown() - {{- end}} } {{- end}} - } - {{- if .IdentifiedBy}} {{.ResourceClassName}}{{$.ParentName}}List = append({{.ResourceClassName}}{{$.ParentName}}List, {{.ResourceClassName}}{{$.ParentName}}) - {{- else}} - {{.ResourceClassName}}{{$.ParentName}}List[0] = {{.ResourceClassName}}{{$.ParentName}} - {{- end}} - {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}},_ = types.SetValueFrom(ctx, {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}}.ElementType(ctx), {{.ResourceClassName}}{{$.ParentName}}List) - } - var data{{.ResourceClassName}}{{.ParentName}}{{.GrandParentName}} []{{.ParentName}}{{.GrandParentName}}ResourceModel - data.{{.ParentName}}.ElementsAs(ctx,&data{{.ResourceClassName}}{{.ParentName}}{{.GrandParentName}},false) - for _, {{.ParentName | lowerFirstCharacter}} := range data{{.ResourceClassName}}{{.ParentName}}{{.GrandParentName}} { - {{.ResourceClassName}}Set, _ := types.SetValueFrom(ctx, {{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementType(ctx),{{.ResourceClassName}}{{.ParentName}}List) - {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}} = {{.ResourceClassName}}Set - if {{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.IsUnknown(){ - {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}} = types.SetNull({{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementType(ctx)) - } - } +} {{- end }} + +{{- define "grandChildDeclarationInChildPayloadFunction" }} +{{.PkgName}}ChildMap := newAciObjectType() +{{- $enteredGrandChildDeclarationZone := false }} +{{- range .Children}} +{{- $enteredGrandChildDeclarationZone = true }} +{{- template "grandChildDeclarationInChildPayloadFunction" . }} +{{- end }} +{{- range .Children}} +{{- if $enteredGrandChildDeclarationZone }} +{{- $enteredGrandChildDeclarationZone = false }} +{{.ParentName}}Children := make([]map[string]interface{}, 0) +{{- end}} +{{- end}} +{{- end}} + +{{- define "rspSubtreeClassFilter" -}} + {{- $currentClasses := listToString .ChildClasses -}} + {{- $currentClasses -}} + {{- range .Children -}} + {{- if not (isListEmpty .ChildClasses) -}} + ,{{- template "rspSubtreeClassFilter" . -}} + {{- end -}} + {{- end -}} +{{- end -}} + diff --git a/internal/provider/resource_aci_communication_policy.go b/internal/provider/resource_aci_communication_policy.go index 251ad4261..11b7bf566 100644 --- a/internal/provider/resource_aci_communication_policy.go +++ b/internal/provider/resource_aci_communication_policy.go @@ -8,7 +8,6 @@ import ( "context" "encoding/json" "fmt" - "log" "reflect" "strings" @@ -87,63 +86,36 @@ type CommHttpsCommPolResourceModel struct { CommRsKeyRing types.Set `tfsdk:"key_ring"` } -func NewCommHttpsCommPolResourceModel() *CommHttpsCommPolResourceModel { - return &CommHttpsCommPolResourceModel{ - AccessControlAllowCredential: types.StringNull(), - AccessControlAllowOrigins: types.StringNull(), - AdminSt: types.StringNull(), - Annotation: types.StringNull(), - CliOnlyMode: types.StringNull(), - ClientCertAuthState: types.StringNull(), - Descr: types.StringNull(), - DhParam: types.StringNull(), - GlobalThrottleRate: types.StringNull(), - GlobalThrottleSt: types.StringNull(), - GlobalThrottleUnit: types.StringNull(), - MaxRequestStatusCount: types.StringNull(), - Name: types.StringNull(), - NameAlias: types.StringNull(), - NodeExporter: types.StringNull(), - Port: types.StringNull(), - Referer: types.StringNull(), - ServerHeader: types.StringNull(), - SslProtocols: types.SetNull(types.StringType), - ThrottleRate: types.StringNull(), - ThrottleSt: types.StringNull(), - VisoreAccess: types.StringNull(), - CommRsClientCertCA: types.SetNull(types.SetType{}), - CommRsKeyRing: types.SetNull(types.SetType{}), - - } +func CommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "access_control_allow_credential": types.StringType, + "access_control_allow_origins": types.StringType, + "admin_st": types.StringType, + "annotation": types.StringType, + "cli_only_mode": types.StringType, + "client_cert_auth_state": types.StringType, + "description": types.StringType, + "dh_param": types.StringType, + "global_throttle_rate": types.StringType, + "global_throttle_st": types.StringType, + "global_throttle_unit": types.StringType, + "max_request_status_count": types.StringType, + "name": types.StringType, + "name_alias": types.StringType, + "node_exporter": types.StringType, + "port": types.StringType, + "referer": types.StringType, + "server_header": types.StringType, + "ssl_protocols": types.SetType{ElemType: types.StringType}, + "throttle_rate": types.StringType, + "throttle_st": types.StringType, + "visore_access": types.StringType, + "tp": types.SetType{ElemType: types.StringType}, + "key_ring": types.SetType{ElemType: types.StringType}, + } } - -func (m CommHttpsCommPolResourceModel) AttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "access_control_allow_credential": types.StringType, - "access_control_allow_origins": types.StringType, - "admin_st": types.StringType, - "annotation": types.StringType, - "cli_only_mode": types.StringType, - "client_cert_auth_state": types.StringType, - "description": types.StringType, - "dh_param": types.StringType, - "global_throttle_rate": types.StringType, - "global_throttle_st": types.StringType, - "global_throttle_unit": types.StringType, - "max_request_status_count": types.StringType, - "name": types.StringType, - "name_alias": types.StringType, - "node_exporter": types.StringType, - "port": types.StringType, - "referer": types.StringType, - "server_header": types.StringType, - "ssl_protocols": types.SetType{ElemType: types.StringType}, - "throttle_rate": types.StringType, - "throttle_st": types.StringType, - "visore_access": types.StringType, - "tp": types.SetType{ElemType: types.StringType}, - "key_ring": types.SetType{ElemType: types.StringType}, - } +func CommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommHttpsCommPolResourceModelAttributeTypes()) } // CommRsClientCertCACommHttpsResourceModel describes the resource data model for the children without relation ships. @@ -153,21 +125,13 @@ type CommRsClientCertCACommHttpsResourceModel struct { } func CommRsClientCertCACommHttpsResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "annotation": types.StringType, - "target_dn": types.StringType, - } + return map[string]attr.Type{ + "annotation": types.StringType, + "target_dn": types.StringType, + } } - func CommRsClientCertCACommHttpsResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{},CommRsClientCertCACommHttpsResourceModelAttributeTypes()) -} - -func NewCommRsClientCertCACommHttpsResourceModel() *CommRsClientCertCACommHttpsResourceModel { - return &CommRsClientCertCACommHttpsResourceModel{ - Annotation: types.StringNull(), - TDn: types.StringNull(), - } + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommRsClientCertCACommHttpsResourceModelAttributeTypes()) } // CommRsKeyRingCommHttpsResourceModel describes the resource data model for the children without relation ships. @@ -176,33 +140,48 @@ type CommRsKeyRingCommHttpsResourceModel struct { TnPkiKeyRingName types.String `tfsdk:"tn_pki_key_ring_name"` } -func (m CommRsKeyRingCommHttpsResourceModel) AttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "annotation": types.StringType, - "tn_pki_key_ring_name": types.StringType, - } +func CommRsKeyRingCommHttpsResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "annotation": types.StringType, + "tn_pki_key_ring_name": types.StringType, + } } - -func NewCommRsKeyRingCommHttpsResourceModel() *CommRsKeyRingCommHttpsResourceModel { - return &CommRsKeyRingCommHttpsResourceModel{ - Annotation: types.StringNull(), - TnPkiKeyRingName: types.StringNull(), - } +func CommRsKeyRingCommHttpsResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommRsKeyRingCommHttpsResourceModelAttributeTypes()) } - // TagAnnotationCommPolResourceModel describes the resource data model for the children without relation ships. type TagAnnotationCommPolResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagAnnotationCommPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagAnnotationCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationCommPolResourceModelAttributeTypes()) +} + // TagTagCommPolResourceModel describes the resource data model for the children without relation ships. type TagTagCommPolResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagCommPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagTagCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagCommPolResourceModelAttributeTypes()) +} + type CommPolIdentifier struct { Name types.String } @@ -300,7 +279,6 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.Set{ setvalidator.SizeAtMost(1), @@ -499,7 +477,6 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.Set{ setvalidator.SizeAtMost(4), @@ -548,8 +525,6 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, Validators: []validator.Set{ setvalidator.SizeAtMost(1), @@ -561,7 +536,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), - //SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The annotation of the Tp object.`, }, @@ -570,7 +545,7 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), - //SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The distinguished name of the target.`, }, @@ -583,8 +558,6 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, Validators: []validator.Set{ setvalidator.SizeAtMost(1), @@ -621,7 +594,6 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -650,7 +622,6 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -852,7 +823,7 @@ func (r *CommPolResource) ImportState(ctx context.Context, req resource.ImportSt } func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *CommPolResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "commPol,commHttps,tagAnnotation,tagTag,commRsClientCertCA,commRsKeyRing"), "GET", nil) if diags.HasError() { return @@ -908,15 +879,15 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl if data.StrictSecurityOnApicOOBSubnet.IsUnknown() { data.StrictSecurityOnApicOOBSubnet = types.StringNull() } - CommHttpsCommPolList := make([]CommHttpsCommPolResourceModel, 1) - var CommHttpsCommPol CommHttpsCommPolResourceModel + CommHttpsCommPol := CommHttpsCommPolResourceModel{} + CommHttpsCommPolList := make([]CommHttpsCommPolResourceModel, 0) + CommRsClientCertCACommHttps := CommRsClientCertCACommHttpsResourceModel{} CommRsClientCertCACommHttpsList := make([]CommRsClientCertCACommHttpsResourceModel, 0) - //var CommRsClientCertCACommHttps2 CommRsClientCertCACommHttpsResourceModel - //var CommRsClientCertCAObject basetypes.ObjectValue - //CommRsClientCertCAObject:=types.ObjectNull(CommRsClientCertCACommHttpsResourceModelAttributeTypes()) - CommRsKeyRingCommHttpsList := make([]CommRsKeyRingCommHttpsResourceModel, 1) - var CommRsKeyRingCommHttps CommRsKeyRingCommHttpsResourceModel + CommRsKeyRingCommHttps := CommRsKeyRingCommHttpsResourceModel{} + CommRsKeyRingCommHttpsList := make([]CommRsKeyRingCommHttpsResourceModel, 0) + TagAnnotationCommPol := TagAnnotationCommPolResourceModel{} TagAnnotationCommPolList := make([]TagAnnotationCommPolResourceModel, 0) + TagTagCommPol := TagTagCommPolResourceModel{} TagTagCommPolList := make([]TagTagCommPolResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -925,7 +896,6 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "commHttps" { - // CommHttpsCommPol := CommHttpsCommPolResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "accessControlAllowCredential" { CommHttpsCommPol.AccessControlAllowCredential = basetypes.NewStringValue(childAttributeValue.(string)) @@ -985,12 +955,9 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl } if childAttributeName == "sslProtocols" { sslProtocolsList := strings.Split(childAttributeValue.(string), ",") - var dataCommHttpsCommPol []CommHttpsCommPolResourceModel - data.CommHttps.ElementsAs(ctx, &dataCommHttpsCommPol, false) - for _, commHttps := range dataCommHttpsCommPol { - sslProtocolsSet, _ := types.SetValueFrom(ctx, commHttps.SslProtocols.ElementType(ctx), sslProtocolsList) - CommHttpsCommPol.SslProtocols = sslProtocolsSet - } + sslProtocolsSet, _ := types.SetValueFrom(ctx, basetypes.StringType{}, sslProtocolsList) + CommHttpsCommPol.SslProtocols = sslProtocolsSet + } if childAttributeName == "throttleRate" { CommHttpsCommPol.ThrottleRate = basetypes.NewStringValue(childAttributeValue.(string)) @@ -1001,85 +968,26 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl if childAttributeName == "visoreAccess" { CommHttpsCommPol.VisoreAccess = basetypes.NewStringValue(childAttributeValue.(string)) } - childClassesCommHttps := childClassDetails.(map[string]interface{})["children"].([]interface{}) - - // for _, childCommHttps := range childClassesCommHttps { - // for childClassNameCommHttps, childClassDetailsCommHttps := range childCommHttps.(map[string]interface{}) { - // if childClassNameCommHttps == "commRsClientCertCA" { - // CommRsClientCertCACommHttps := CommRsClientCertCACommHttpsResourceModel{} - - // commRsClientCertCAchildAttributeValue := childClassDetailsCommHttps.(map[string]interface{})["attributes"].(map[string]interface{}) - // for childAttributeName, childAttributeValue := range commRsClientCertCAchildAttributeValue { - // if childAttributeName == "annotation" { - // CommRsClientCertCACommHttps.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) - // } - // if childAttributeName == "tDn" { - // CommRsClientCertCACommHttps.TDn = basetypes.NewStringValue(childAttributeValue.(string)) - // } - // if CommRsClientCertCACommHttps.Annotation.IsUnknown() { - // CommRsClientCertCACommHttps.Annotation = types.StringNull(), - // } - // if CommRsClientCertCACommHttps.TDn.IsUnknown() { - // CommRsClientCertCACommHttps.TDn = types.StringNull(), - // } - // } - // CommRsClientCertCACommHttpsList[0] = CommRsClientCertCACommHttps - // CommHttpsCommPol.CommRsClientCertCA, _ = types.SetValueFrom(ctx, CommHttpsCommPol.CommRsClientCertCA.ElementType(ctx), CommRsClientCertCACommHttpsList) - // } - - - - // type ObjectAsOptions struct { - // // UnhandledNullAsEmpty controls what happens when As needs to put a - // // null value in a type that has no way to preserve that distinction. - // // When set to true, the type's empty value will be used. When set to - // // false, an error will be returned. - // UnhandledNullAsEmpty bool - - // // UnhandledUnknownAsEmpty controls what happens when As needs to put - // // an unknown value in a type that has no way to preserve that - // // distinction. When set to true, the type's empty value will be used. - // // When set to false, an error will be returned. - // UnhandledUnknownAsEmpty bool - // } - - for _, childCommHttps := range childClassesCommHttps { - for childClassNameCommHttps, childClassDetailsCommHttps := range childCommHttps.(map[string]interface{}) { - if childClassNameCommHttps == "commRsClientCertCA" { - var CommRsClientCertCACommHttps CommRsClientCertCACommHttpsResourceModel - commRsClientCertCAchildAttributes := childClassDetailsCommHttps.(map[string]interface{})["attributes"].(map[string]interface{}) - - // Set the known attributes. - if annotation, ok := commRsClientCertCAchildAttributes["annotation"].(string); ok { - CommRsClientCertCACommHttps.Annotation = basetypes.NewStringValue(annotation) - } - if tDn, ok := commRsClientCertCAchildAttributes["tDn"].(string); ok { - CommRsClientCertCACommHttps.TDn = basetypes.NewStringValue(tDn) - } - - //CommRsClientCertCAObject, _ = types.ObjectValueFrom(ctx, CommRsClientCertCACommHttpsResourceModelAttributeTypes(), CommRsClientCertCACommHttps) - CommRsClientCertCACommHttpsList = append(CommRsClientCertCACommHttpsList, CommRsClientCertCACommHttps) - + + } + _, childrenOfCommHttpsExist := childClassDetails.(map[string]interface{})["children"] + if childrenOfCommHttpsExist { + childClassesOfCommHttps := childClassDetails.(map[string]interface{})["children"].([]interface{}) + for _, childCommHttps := range childClassesOfCommHttps { + for childClassNameCommHttps, childClassDetailsCommHttps := range childCommHttps.(map[string]interface{}) { + if childClassNameCommHttps == "commRsClientCertCA" { + commRsClientCertCAchildAttributeValue := childClassDetailsCommHttps.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range commRsClientCertCAchildAttributeValue { + if childAttributeName == "annotation" { + CommRsClientCertCACommHttps.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "tDn" { + CommRsClientCertCACommHttps.TDn = basetypes.NewStringValue(childAttributeValue.(string)) } - - // if CommHttpsCommPol.CommRsClientCertCA.IsUnknown() || CommHttpsCommPol.CommRsClientCertCA.IsNull() { - - // CommHttpsCommPol.CommRsClientCertCA = types.ObjectNull(CommRsClientCertCACommHttps.AttributeTypes()) - // } - - // var dataCommRsClientCertCACommHttpsCommPol []CommHttpsCommPolResourceModel - // data.CommHttps.ElementsAs(ctx, &dataCommRsClientCertCACommHttpsCommPol, false) - // for _, commHttps := range dataCommRsClientCertCACommHttpsCommPol { - // // CommRsClientCertCAObject, _ := types.SetValueFrom(ctx, commHttps.CommRsClientCertCA.ElementType(ctx), CommRsClientCertCACommHttpsList) - // // CommHttpsCommPol.CommRsClientCertCA = CommRsClientCertCAObject - // log.Printf("Here %v",commHttps.CommRsClientCertCA.ElementType(ctx)) - // if commHttps.CommRsClientCertCA.IsUnknown() || commHttps.CommRsClientCertCA.IsNull() { - - // CommHttpsCommPol.CommRsClientCertCA = types.SetNull(commHttps.CommRsClientCertCA.ElementType(ctx)) - // } - // } + } + CommRsClientCertCACommHttpsList = append(CommRsClientCertCACommHttpsList, CommRsClientCertCACommHttps) + } if childClassNameCommHttps == "commRsKeyRing" { - // CommRsKeyRingCommHttps := CommRsKeyRingCommHttpsResourceModel{} commRsKeyRingchildAttributeValue := childClassDetailsCommHttps.(map[string]interface{})["attributes"].(map[string]interface{}) for childAttributeName, childAttributeValue := range commRsKeyRingchildAttributeValue { if childAttributeName == "annotation" { @@ -1088,146 +996,27 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl if childAttributeName == "tnPkiKeyRingName" { CommRsKeyRingCommHttps.TnPkiKeyRingName = basetypes.NewStringValue(childAttributeValue.(string)) } - // if CommRsKeyRingCommHttps.Annotation.IsUnknown() { - // CommRsKeyRingCommHttps.Annotation = types.StringNull(), - // } - // if CommRsKeyRingCommHttps.TnPkiKeyRingName.IsUnknown() { - // CommRsKeyRingCommHttps.TnPkiKeyRingName = types.StringNull(), - // } } - CommRsKeyRingCommHttpsList[0] = CommRsKeyRingCommHttps - //CommHttpsCommPol.CommRsKeyRing, _ = types.SetValueFrom(ctx, CommHttpsCommPol.CommRsKeyRing.ElementType(ctx), CommRsKeyRingCommHttpsList) + CommRsKeyRingCommHttpsList = append(CommRsKeyRingCommHttpsList, CommRsKeyRingCommHttps) } - // var dataCommRsKeyRingCommHttpsCommPol []CommHttpsCommPolResourceModel - // data.CommHttps.ElementsAs(ctx, &dataCommRsKeyRingCommHttpsCommPol, false) - // for _, commHttps := range dataCommRsKeyRingCommHttpsCommPol { - // CommRsKeyRingObject, _ := types.SetValueFrom(ctx, commHttps.CommRsKeyRing.ElementType(ctx), CommRsKeyRingCommHttpsList) - // CommHttpsCommPol.CommRsKeyRing = CommRsKeyRingObject - // if commHttps.CommRsKeyRing.IsUnknown() { - // CommHttpsCommPol.CommRsKeyRing = types.SetNull(commHttps.CommRsKeyRing.ElementType(ctx)) - // } - // } } } } - - // CommRsClientCertCAObject,diag:=types.SetValueFrom(ctx,types.StringType,CommRsClientCertCACommHttpsList) - // CommHttpsCommPol.CommRsClientCertCA=CommRsClientCertCAObject - //log.Printf("HERE from set %v %v",CommHttpsCommPol.CommRsClientCertCA, diag) - //basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{},CommRsClientCertCACommHttpsResourceModelAttributeTypes()) if len(CommRsClientCertCACommHttpsList) > 0 { - CommRsClientCertCASet,_:=types.SetValueFrom(ctx,CommRsClientCertCACommHttpsResourceModelElementType(),CommRsClientCertCACommHttpsList) - CommHttpsCommPol.CommRsClientCertCA=CommRsClientCertCASet - } else{ - CommHttpsCommPol.CommRsClientCertCA=types.SetNull(CommRsClientCertCACommHttpsResourceModelElementType()) + CommRsClientCertCASet, _ := types.SetValueFrom(ctx, CommRsClientCertCACommHttpsResourceModelElementType(), CommRsClientCertCACommHttpsList) + CommHttpsCommPol.CommRsClientCertCA = CommRsClientCertCASet + } else { + CommHttpsCommPol.CommRsClientCertCA = types.SetNull(CommRsClientCertCACommHttpsResourceModelElementType()) } - // log.Printf("here CA WithAttr %v",CommRsClientCertCACommHttpsResourceModelElementType()) - // if !CommRsClientCertCAObject.IsNull(){ - // log.Printf("here CA inside %v %v %v",CommRsClientCertCAObject,CommRsClientCertCAObject.IsNull(),CommRsClientCertCAObject.IsUnknown()) - // CommHttpsCommPol.CommRsClientCertCA,_=types.SetValue(CommRsClientCertCAObject.Type(ctx),[]attr.Value{CommRsClientCertCAObject}) - // } else{ - // log.Printf("here CA else %v %v %v",CommRsClientCertCAObject,CommRsClientCertCAObject.IsNull(),CommRsClientCertCAObject.IsUnknown()) - // CommHttpsCommPol.CommRsClientCertCA=types.SetNull(CommRsClientCertCAObject.Type(ctx)) - // } - // if !areAllStringFieldsEmpty(*CommRsClientCertCACommHttps) { - // CommHttpsCommPol.CommRsClientCertCA,_=types.SetValue(CommRsClientCertCAObject.Type(ctx),[]attr.Value{CommRsClientCertCAObject}) - // log.Printf("here ca0 %v",CommHttpsCommPol.CommRsClientCertCA) - // } else{ - // CommHttpsCommPol.CommRsClientCertCA=types.SetNull(CommRsClientCertCAObject.Type(ctx)) - // log.Printf("here ca1 %v",CommHttpsCommPol.CommRsClientCertCA) - // } - CommRsKeyRingObject, _ := types.ObjectValueFrom(ctx, CommRsKeyRingCommHttps.AttributeTypes(), CommRsKeyRingCommHttpsList[0]) - CommHttpsCommPol.CommRsKeyRing,_=types.SetValue(CommRsKeyRingObject.Type(ctx),[]attr.Value{CommRsKeyRingObject}) - // if !areAllStringFieldsEmpty(*CommRsKeyRingCommHttps) { - // CommHttpsCommPol.CommRsKeyRing,_=types.SetValue(CommRsKeyRingObject.Type(ctx),[]attr.Value{CommRsKeyRingObject}) - // log.Printf("here kr0 %v",CommHttpsCommPol.CommRsKeyRing) - // } else{ - // CommHttpsCommPol.CommRsKeyRing=types.SetNull(CommRsKeyRingObject.Type(ctx)) - // log.Printf("here kr1 %v",CommHttpsCommPol.CommRsKeyRing) - // } - - - - // if CommHttpsCommPol.CommRsClientCertCA.IsUnknown() || CommHttpsCommPol.CommRsClientCertCA.IsNull() { - // log.Printf("HERE in") - // log.Printf("HERE CertCA %v %v %v",CommHttpsCommPol.CommRsClientCertCA,CommHttpsCommPol.CommRsClientCertCA.IsUnknown(), CommHttpsCommPol.CommRsClientCertCA.IsNull()) - // CommHttpsCommPol.CommRsClientCertCA = basetypes.NewSetNull(CommRsKeyRingObject.Type(ctx)) - // } - //log.Printf("HERE CertCA %v %v",CommHttpsCommPol.CommRsClientCertCA, CommRsClientCertCAObject) - //log.Printf("HERE KeyRIng %v %v",CommHttpsCommPol.CommRsKeyRing,CommRsKeyRingObject) - // if CommHttpsCommPol.AccessControlAllowCredential.IsUnknown() { - // CommHttpsCommPol.AccessControlAllowCredential = types.StringNull(), - // } - // if CommHttpsCommPol.AccessControlAllowOrigins.IsUnknown() { - // CommHttpsCommPol.AccessControlAllowOrigins = types.StringNull(), - // } - // if CommHttpsCommPol.AdminSt.IsUnknown() { - // CommHttpsCommPol.AdminSt = types.StringNull(), - // } - // if CommHttpsCommPol.Annotation.IsUnknown() { - // CommHttpsCommPol.Annotation = types.StringNull(), - // } - // if CommHttpsCommPol.CliOnlyMode.IsUnknown() { - // CommHttpsCommPol.CliOnlyMode = types.StringNull(), - // } - // if CommHttpsCommPol.ClientCertAuthState.IsUnknown() { - // CommHttpsCommPol.ClientCertAuthState = types.StringNull(), - // } - // if CommHttpsCommPol.Descr.IsUnknown() { - // CommHttpsCommPol.Descr = types.StringNull(), - // } - // if CommHttpsCommPol.DhParam.IsUnknown() { - // CommHttpsCommPol.DhParam = types.StringNull(), - // } - // if CommHttpsCommPol.GlobalThrottleRate.IsUnknown() { - // CommHttpsCommPol.GlobalThrottleRate = types.StringNull(), - // } - // if CommHttpsCommPol.GlobalThrottleSt.IsUnknown() { - // CommHttpsCommPol.GlobalThrottleSt = types.StringNull(), - // } - // if CommHttpsCommPol.GlobalThrottleUnit.IsUnknown() { - // CommHttpsCommPol.GlobalThrottleUnit = types.StringNull(), - // } - // if CommHttpsCommPol.MaxRequestStatusCount.IsUnknown() { - // CommHttpsCommPol.MaxRequestStatusCount = types.StringNull(), - // } - // if CommHttpsCommPol.Name.IsUnknown() { - // CommHttpsCommPol.Name = types.StringNull(), - // } - // if CommHttpsCommPol.NameAlias.IsUnknown() { - // CommHttpsCommPol.NameAlias = types.StringNull(), - // } - // if CommHttpsCommPol.NodeExporter.IsUnknown() { - // CommHttpsCommPol.NodeExporter = types.StringNull(), - // } - // if CommHttpsCommPol.Referer.IsNull() { - // CommHttpsCommPol.Referer = types.StringNull(), - // } - // if CommHttpsCommPol.ServerHeader.IsUnknown() { - // CommHttpsCommPol.ServerHeader = types.StringNull(), - // } - // if CommHttpsCommPol.SslProtocols.IsUnknown() { - // var datasslProtocolsCommHttpsCommPol []CommHttpsCommPolResourceModel - // data.CommHttps.ElementsAs(ctx, &datasslProtocolsCommHttpsCommPol, false) - // for _, commHttps := range datasslProtocolsCommHttpsCommPol { - // if CommHttpsCommPol.SslProtocols.IsUnknown() { - // CommHttpsCommPol.SslProtocols = types.SetNull(commHttps.SslProtocols.ElementType(ctx)) - // } - // } - // } - // if CommHttpsCommPol.ThrottleRate.IsUnknown() { - // CommHttpsCommPol.ThrottleRate = types.StringNull(), - // } - // if CommHttpsCommPol.ThrottleSt.IsUnknown() { - // CommHttpsCommPol.ThrottleSt = types.StringNull(), - // } - // if CommHttpsCommPol.VisoreAccess.IsUnknown() { - // CommHttpsCommPol.VisoreAccess = types.StringNull(), - // } - CommHttpsCommPolList[0] = CommHttpsCommPol + if len(CommRsKeyRingCommHttpsList) > 0 { + CommRsKeyRingSet, _ := types.SetValueFrom(ctx, CommRsKeyRingCommHttpsResourceModelElementType(), CommRsKeyRingCommHttpsList) + CommHttpsCommPol.CommRsKeyRing = CommRsKeyRingSet + } else { + CommHttpsCommPol.CommRsKeyRing = types.SetNull(CommRsKeyRingCommHttpsResourceModelElementType()) + } + CommHttpsCommPolList = append(CommHttpsCommPolList, CommHttpsCommPol) } if childClassName == "tagAnnotation" { - TagAnnotationCommPol := TagAnnotationCommPolResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -1235,17 +1024,11 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl if childAttributeName == "value" { TagAnnotationCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagAnnotationCommPol.Key.IsUnknown() { - TagAnnotationCommPol.Key = types.StringNull() - } - if TagAnnotationCommPol.Value.IsUnknown() { - TagAnnotationCommPol.Value = types.StringNull() + } TagAnnotationCommPolList = append(TagAnnotationCommPolList, TagAnnotationCommPol) } if childClassName == "tagTag" { - TagTagCommPol := TagTagCommPolResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -1253,12 +1036,7 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl if childAttributeName == "value" { TagTagCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagTagCommPol.Key.IsUnknown() { - TagTagCommPol.Key = types.StringNull() - } - if TagTagCommPol.Value.IsUnknown() { - TagTagCommPol.Value = types.StringNull() + } TagTagCommPolList = append(TagTagCommPolList, TagTagCommPol) } @@ -1266,16 +1044,10 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl } } if len(CommHttpsCommPolList) > 0 { - commHttpsSet, _ := types.SetValueFrom(ctx, data.CommHttps.ElementType(ctx),CommHttpsCommPolList) - data.CommHttps=commHttpsSet - // commHttpsSet, diags := types.ObjectValueFrom(ctx, CommHttpsCommPol.AttributeTypes(), CommHttpsCommPolList[0]) - log.Printf("HERE %v %v %v",CommHttpsCommPolList,commHttpsSet, diags) - - // data.CommHttps = types.SetValueMust(commHttpsSet.Type(ctx),[]attr.Value{commHttpsSet}) - log.Printf("HERE %v %v %v",commHttpsSet,data.CommHttps,diags) + commHttpsSet, _ := types.SetValueFrom(ctx, data.CommHttps.ElementType(ctx), CommHttpsCommPolList) + data.CommHttps = commHttpsSet } if len(TagAnnotationCommPolList) > 0 { - log.Printf("HERE TAG %v",data.TagAnnotation.ElementType(ctx)) tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationCommPolList) data.TagAnnotation = tagAnnotationSet } @@ -1310,24 +1082,11 @@ func setCommPolId(ctx context.Context, data *CommPolResourceModel) { } func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, commHttpsPlan, commHttpsState []CommHttpsCommPolResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } - CommHttpsChildren := make([]map[string]interface{}, 0) - commRsClientCertCAChildMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } - commRsKeyRingChildMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} + commRsClientCertCAChildMap := newAciObjectType() + commRsKeyRingChildMap := newAciObjectType() + CommHttpsChildren := make([]map[string]interface{}, 0) if !data.CommHttps.IsUnknown() { for _, commHttps := range commHttpsPlan { if !commHttps.AccessControlAllowCredential.IsUnknown() { @@ -1400,18 +1159,14 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti if !commHttps.VisoreAccess.IsUnknown() { childMap.Attributes["visoreAccess"] = commHttps.VisoreAccess.ValueString() } - var commRsClientCertCAPlan, commRsClientCertCAState []CommRsClientCertCACommHttpsResourceModel - for i, commHttps := range commHttpsPlan { - commHttps.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCAPlan, false) - commHttpsPlan[i].CommRsClientCertCA, _ = types.SetValueFrom(ctx, commHttps.CommRsClientCertCA.ElementType(ctx), commRsClientCertCAPlan) - } - for i, commHttps := range commHttpsState { - commHttps.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCAState, false) - commHttpsState[i].CommRsClientCertCA, _ = types.SetValueFrom(ctx, commHttps.CommRsClientCertCA.ElementType(ctx), commRsClientCertCAState) - } - if len(commRsClientCertCAPlan) == 0 && len(commRsClientCertCAState) == 1 { - commRsClientCertCAChildMap.Attributes["status"] = "deleted" - CommHttpsChildren = append(CommHttpsChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCAChildMap}) + var commRsClientCertCAPlan []CommRsClientCertCACommHttpsResourceModel + commHttps.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCAPlan, false) + for _, commHttpscommRsClientCertCA := range commHttpsState { + if len(commRsClientCertCAPlan) == 0 && len(commHttpscommRsClientCertCA.CommRsClientCertCA.Elements()) == 1 { + commRsClientCertCAChildMap := newAciObjectType() + commRsClientCertCAChildMap.Attributes["status"] = "deleted" + CommHttpsChildren = append(CommHttpsChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCAChildMap}) + } } if !commHttps.CommRsClientCertCA.IsUnknown() { for _, commRsClientCertCA := range commRsClientCertCAPlan { @@ -1426,22 +1181,16 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti CommHttpsChildren = append(CommHttpsChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCAChildMap}) } } - //childMap.Children = CommHttpsChildren - var commRsKeyRingPlan, commRsKeyRingState []CommRsKeyRingCommHttpsResourceModel - for i, commHttps := range commHttpsPlan { - commHttps.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingPlan, false) - commHttpsPlan[i].CommRsKeyRing, _ = types.SetValueFrom(ctx, commHttps.CommRsKeyRing.ElementType(ctx), commRsKeyRingPlan) - } - for i, commHttps := range commHttpsState { - commHttps.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingState, false) - commHttpsState[i].CommRsKeyRing, _ = types.SetValueFrom(ctx, commHttps.CommRsKeyRing.ElementType(ctx), commRsKeyRingState) - } - if len(commRsKeyRingPlan) == 0 && len(commRsKeyRingState) == 1 { - diags.AddError( - "CommRsKeyRing object cannot be deleted", - "deletion of child is only possible upon deletion of the parent", - ) - return nil + var commRsKeyRingPlan []CommRsKeyRingCommHttpsResourceModel + commHttps.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingPlan, false) + for _, commHttpscommRsKeyRing := range commHttpsState { + if len(commRsKeyRingPlan) == 0 && len(commHttpscommRsKeyRing.CommRsKeyRing.Elements()) == 1 { + diags.AddError( + "CommRsKeyRing object cannot be deleted", + "deletion of child is only possible upon deletion of the parent", + ) + return nil + } } if !commHttps.CommRsKeyRing.IsUnknown() { for _, commRsKeyRing := range commRsKeyRingPlan { @@ -1474,14 +1223,7 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti } func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationCommPolResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} @@ -1506,12 +1248,10 @@ func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagn } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -1522,14 +1262,7 @@ func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagn } func getCommPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, tagTagPlan, tagTagState []TagTagCommPolResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} @@ -1554,12 +1287,10 @@ func getCommPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { diff --git a/internal/provider/resource_aci_endpoint_tag_ip.go b/internal/provider/resource_aci_endpoint_tag_ip.go index 5aed24f26..f01e3cdfd 100644 --- a/internal/provider/resource_aci_endpoint_tag_ip.go +++ b/internal/provider/resource_aci_endpoint_tag_ip.go @@ -13,6 +13,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -59,12 +60,32 @@ type TagAnnotationFvEpIpTagResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationFvEpIpTagResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagAnnotationFvEpIpTagResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvEpIpTagResourceModelAttributeTypes()) +} + // TagTagFvEpIpTagResourceModel describes the resource data model for the children without relation ships. type TagTagFvEpIpTagResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagFvEpIpTagResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagTagFvEpIpTagResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvEpIpTagResourceModelAttributeTypes()) +} + type FvEpIpTagIdentifier struct { CtxName types.String Ip types.String @@ -159,7 +180,6 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -188,7 +208,6 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -384,7 +403,7 @@ func (r *FvEpIpTagResource) ImportState(ctx context.Context, req resource.Import } func getAndSetFvEpIpTagAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *FvEpIpTagResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "fvEpIpTag,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -435,7 +454,9 @@ func getAndSetFvEpIpTagAttributes(ctx context.Context, diags *diag.Diagnostics, if data.NameAlias.IsUnknown() { data.NameAlias = types.StringNull() } + TagAnnotationFvEpIpTag := TagAnnotationFvEpIpTagResourceModel{} TagAnnotationFvEpIpTagList := make([]TagAnnotationFvEpIpTagResourceModel, 0) + TagTagFvEpIpTag := TagTagFvEpIpTagResourceModel{} TagTagFvEpIpTagList := make([]TagTagFvEpIpTagResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -444,7 +465,6 @@ func getAndSetFvEpIpTagAttributes(ctx context.Context, diags *diag.Diagnostics, for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "tagAnnotation" { - TagAnnotationFvEpIpTag := TagAnnotationFvEpIpTagResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationFvEpIpTag.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -452,17 +472,11 @@ func getAndSetFvEpIpTagAttributes(ctx context.Context, diags *diag.Diagnostics, if childAttributeName == "value" { TagAnnotationFvEpIpTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagAnnotationFvEpIpTag.Key.IsUnknown() { - TagAnnotationFvEpIpTag.Key = types.StringNull() - } - if TagAnnotationFvEpIpTag.Value.IsUnknown() { - TagAnnotationFvEpIpTag.Value = types.StringNull() + } TagAnnotationFvEpIpTagList = append(TagAnnotationFvEpIpTagList, TagAnnotationFvEpIpTag) } if childClassName == "tagTag" { - TagTagFvEpIpTag := TagTagFvEpIpTagResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagFvEpIpTag.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -470,12 +484,7 @@ func getAndSetFvEpIpTagAttributes(ctx context.Context, diags *diag.Diagnostics, if childAttributeName == "value" { TagTagFvEpIpTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagTagFvEpIpTag.Key.IsUnknown() { - TagTagFvEpIpTag.Key = types.StringNull() - } - if TagTagFvEpIpTag.Value.IsUnknown() { - TagTagFvEpIpTag.Value = types.StringNull() + } TagTagFvEpIpTagList = append(TagTagFvEpIpTagList, TagTagFvEpIpTag) } @@ -531,14 +540,7 @@ func setFvEpIpTagId(ctx context.Context, data *FvEpIpTagResourceModel) { } func getFvEpIpTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpIpTagResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} @@ -563,12 +565,10 @@ func getFvEpIpTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -579,14 +579,7 @@ func getFvEpIpTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } func getFvEpIpTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagTagPlan, tagTagState []TagTagFvEpIpTagResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} @@ -611,12 +604,10 @@ func getFvEpIpTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostic } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { diff --git a/internal/provider/resource_aci_endpoint_tag_mac.go b/internal/provider/resource_aci_endpoint_tag_mac.go index db1dfdb5a..d234cc331 100644 --- a/internal/provider/resource_aci_endpoint_tag_mac.go +++ b/internal/provider/resource_aci_endpoint_tag_mac.go @@ -13,6 +13,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -59,12 +60,32 @@ type TagAnnotationFvEpMacTagResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationFvEpMacTagResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagAnnotationFvEpMacTagResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvEpMacTagResourceModelAttributeTypes()) +} + // TagTagFvEpMacTagResourceModel describes the resource data model for the children without relation ships. type TagTagFvEpMacTagResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagFvEpMacTagResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagTagFvEpMacTagResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvEpMacTagResourceModelAttributeTypes()) +} + type FvEpMacTagIdentifier struct { BdName types.String Mac types.String @@ -159,7 +180,6 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -188,7 +208,6 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -384,7 +403,7 @@ func (r *FvEpMacTagResource) ImportState(ctx context.Context, req resource.Impor } func getAndSetFvEpMacTagAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *FvEpMacTagResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "fvEpMacTag,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -435,7 +454,9 @@ func getAndSetFvEpMacTagAttributes(ctx context.Context, diags *diag.Diagnostics, if data.NameAlias.IsUnknown() { data.NameAlias = types.StringNull() } + TagAnnotationFvEpMacTag := TagAnnotationFvEpMacTagResourceModel{} TagAnnotationFvEpMacTagList := make([]TagAnnotationFvEpMacTagResourceModel, 0) + TagTagFvEpMacTag := TagTagFvEpMacTagResourceModel{} TagTagFvEpMacTagList := make([]TagTagFvEpMacTagResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -444,7 +465,6 @@ func getAndSetFvEpMacTagAttributes(ctx context.Context, diags *diag.Diagnostics, for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "tagAnnotation" { - TagAnnotationFvEpMacTag := TagAnnotationFvEpMacTagResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationFvEpMacTag.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -452,17 +472,11 @@ func getAndSetFvEpMacTagAttributes(ctx context.Context, diags *diag.Diagnostics, if childAttributeName == "value" { TagAnnotationFvEpMacTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagAnnotationFvEpMacTag.Key.IsUnknown() { - TagAnnotationFvEpMacTag.Key = types.StringNull() - } - if TagAnnotationFvEpMacTag.Value.IsUnknown() { - TagAnnotationFvEpMacTag.Value = types.StringNull() + } TagAnnotationFvEpMacTagList = append(TagAnnotationFvEpMacTagList, TagAnnotationFvEpMacTag) } if childClassName == "tagTag" { - TagTagFvEpMacTag := TagTagFvEpMacTagResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagFvEpMacTag.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -470,12 +484,7 @@ func getAndSetFvEpMacTagAttributes(ctx context.Context, diags *diag.Diagnostics, if childAttributeName == "value" { TagTagFvEpMacTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagTagFvEpMacTag.Key.IsUnknown() { - TagTagFvEpMacTag.Key = types.StringNull() - } - if TagTagFvEpMacTag.Value.IsUnknown() { - TagTagFvEpMacTag.Value = types.StringNull() + } TagTagFvEpMacTagList = append(TagTagFvEpMacTagList, TagTagFvEpMacTag) } @@ -531,14 +540,7 @@ func setFvEpMacTagId(ctx context.Context, data *FvEpMacTagResourceModel) { } func getFvEpMacTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpMacTagResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} @@ -563,12 +565,10 @@ func getFvEpMacTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -579,14 +579,7 @@ func getFvEpMacTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di } func getFvEpMacTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagTagPlan, tagTagState []TagTagFvEpMacTagResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} @@ -611,12 +604,10 @@ func getFvEpMacTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnosti } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { 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 29153bd08..107c81d25 100644 --- a/internal/provider/resource_aci_external_management_network_instance_profile.go +++ b/internal/provider/resource_aci_external_management_network_instance_profile.go @@ -14,6 +14,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -61,18 +62,49 @@ type MgmtRsOoBConsMgmtInstPResourceModel struct { TnVzOOBBrCPName types.String `tfsdk:"out_of_band_contract_name"` } +func MgmtRsOoBConsMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "annotation": types.StringType, + "priority": types.StringType, + "out_of_band_contract_name": types.StringType, + } +} +func MgmtRsOoBConsMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, MgmtRsOoBConsMgmtInstPResourceModelAttributeTypes()) +} + // TagAnnotationMgmtInstPResourceModel describes the resource data model for the children without relation ships. type TagAnnotationMgmtInstPResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagAnnotationMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagAnnotationMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtInstPResourceModelAttributeTypes()) +} + // TagTagMgmtInstPResourceModel describes the resource data model for the children without relation ships. type TagTagMgmtInstPResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagTagMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtInstPResourceModelAttributeTypes()) +} + type MgmtInstPIdentifier struct { Name types.String } @@ -152,7 +184,6 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -194,7 +225,6 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -223,7 +253,6 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -425,7 +454,7 @@ func (r *MgmtInstPResource) ImportState(ctx context.Context, req resource.Import } func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *MgmtInstPResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtInstP,mgmtRsOoBCons,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -469,8 +498,11 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, if data.Prio.IsUnknown() { data.Prio = types.StringNull() } + MgmtRsOoBConsMgmtInstP := MgmtRsOoBConsMgmtInstPResourceModel{} MgmtRsOoBConsMgmtInstPList := make([]MgmtRsOoBConsMgmtInstPResourceModel, 0) + TagAnnotationMgmtInstP := TagAnnotationMgmtInstPResourceModel{} TagAnnotationMgmtInstPList := make([]TagAnnotationMgmtInstPResourceModel, 0) + TagTagMgmtInstP := TagTagMgmtInstPResourceModel{} TagTagMgmtInstPList := make([]TagTagMgmtInstPResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -479,7 +511,6 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "mgmtRsOoBCons" { - MgmtRsOoBConsMgmtInstP := MgmtRsOoBConsMgmtInstPResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "annotation" { MgmtRsOoBConsMgmtInstP.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) @@ -490,20 +521,11 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, if childAttributeName == "tnVzOOBBrCPName" { MgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if MgmtRsOoBConsMgmtInstP.Annotation.IsUnknown() { - MgmtRsOoBConsMgmtInstP.Annotation = types.StringNull() - } - if MgmtRsOoBConsMgmtInstP.Prio.IsUnknown() { - MgmtRsOoBConsMgmtInstP.Prio = types.StringNull() - } - if MgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName.IsUnknown() { - MgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName = types.StringNull() + } MgmtRsOoBConsMgmtInstPList = append(MgmtRsOoBConsMgmtInstPList, MgmtRsOoBConsMgmtInstP) } if childClassName == "tagAnnotation" { - TagAnnotationMgmtInstP := TagAnnotationMgmtInstPResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationMgmtInstP.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -511,17 +533,11 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, if childAttributeName == "value" { TagAnnotationMgmtInstP.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagAnnotationMgmtInstP.Key.IsUnknown() { - TagAnnotationMgmtInstP.Key = types.StringNull() - } - if TagAnnotationMgmtInstP.Value.IsUnknown() { - TagAnnotationMgmtInstP.Value = types.StringNull() + } TagAnnotationMgmtInstPList = append(TagAnnotationMgmtInstPList, TagAnnotationMgmtInstP) } if childClassName == "tagTag" { - TagTagMgmtInstP := TagTagMgmtInstPResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagMgmtInstP.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -529,12 +545,7 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, if childAttributeName == "value" { TagTagMgmtInstP.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagTagMgmtInstP.Key.IsUnknown() { - TagTagMgmtInstP.Key = types.StringNull() - } - if TagTagMgmtInstP.Value.IsUnknown() { - TagTagMgmtInstP.Value = types.StringNull() + } TagTagMgmtInstPList = append(TagTagMgmtInstPList, TagTagMgmtInstP) } @@ -574,14 +585,7 @@ func setMgmtInstPId(ctx context.Context, data *MgmtInstPResourceModel) { } func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, mgmtRsOoBConsPlan, mgmtRsOoBConsState []MgmtRsOoBConsMgmtInstPResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.MgmtRsOoBCons.IsUnknown() { mgmtRsOoBConsIdentifiers := []MgmtRsOoBConsIdentifier{} @@ -611,12 +615,10 @@ func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["tnVzOOBBrCPName"] = mgmtRsOoBCons.TnVzOOBBrCPName.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"mgmtRsOoBCons": childMap}) + mgmtRsOoBConsChildMapForDelete := newAciObjectType() + mgmtRsOoBConsChildMapForDelete.Attributes["status"] = "deleted" + mgmtRsOoBConsChildMapForDelete.Attributes["tnVzOOBBrCPName"] = mgmtRsOoBCons.TnVzOOBBrCPName.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"mgmtRsOoBCons": mgmtRsOoBConsChildMapForDelete}) } } } else { @@ -627,14 +629,7 @@ func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Dia } func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtInstPResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} @@ -659,12 +654,10 @@ func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -675,14 +668,7 @@ func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } func getMgmtInstPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagTagPlan, tagTagState []TagTagMgmtInstPResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} @@ -707,12 +693,10 @@ func getMgmtInstPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostic } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { diff --git a/internal/provider/resource_aci_external_management_network_subnet.go b/internal/provider/resource_aci_external_management_network_subnet.go index 5b0e62612..503bd5322 100644 --- a/internal/provider/resource_aci_external_management_network_subnet.go +++ b/internal/provider/resource_aci_external_management_network_subnet.go @@ -13,6 +13,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -58,12 +59,32 @@ type TagAnnotationMgmtSubnetResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationMgmtSubnetResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagAnnotationMgmtSubnetResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtSubnetResourceModelAttributeTypes()) +} + // TagTagMgmtSubnetResourceModel describes the resource data model for the children without relation ships. type TagTagMgmtSubnetResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagMgmtSubnetResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagTagMgmtSubnetResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtSubnetResourceModelAttributeTypes()) +} + type MgmtSubnetIdentifier struct { Ip types.String } @@ -148,7 +169,6 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -177,7 +197,6 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -373,7 +392,7 @@ func (r *MgmtSubnetResource) ImportState(ctx context.Context, req resource.Impor } func getAndSetMgmtSubnetAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *MgmtSubnetResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtSubnet,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -418,7 +437,9 @@ func getAndSetMgmtSubnetAttributes(ctx context.Context, diags *diag.Diagnostics, if data.NameAlias.IsUnknown() { data.NameAlias = types.StringNull() } + TagAnnotationMgmtSubnet := TagAnnotationMgmtSubnetResourceModel{} TagAnnotationMgmtSubnetList := make([]TagAnnotationMgmtSubnetResourceModel, 0) + TagTagMgmtSubnet := TagTagMgmtSubnetResourceModel{} TagTagMgmtSubnetList := make([]TagTagMgmtSubnetResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -427,7 +448,6 @@ func getAndSetMgmtSubnetAttributes(ctx context.Context, diags *diag.Diagnostics, for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "tagAnnotation" { - TagAnnotationMgmtSubnet := TagAnnotationMgmtSubnetResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationMgmtSubnet.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -435,17 +455,11 @@ func getAndSetMgmtSubnetAttributes(ctx context.Context, diags *diag.Diagnostics, if childAttributeName == "value" { TagAnnotationMgmtSubnet.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagAnnotationMgmtSubnet.Key.IsUnknown() { - TagAnnotationMgmtSubnet.Key = types.StringNull() - } - if TagAnnotationMgmtSubnet.Value.IsUnknown() { - TagAnnotationMgmtSubnet.Value = types.StringNull() + } TagAnnotationMgmtSubnetList = append(TagAnnotationMgmtSubnetList, TagAnnotationMgmtSubnet) } if childClassName == "tagTag" { - TagTagMgmtSubnet := TagTagMgmtSubnetResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagMgmtSubnet.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -453,12 +467,7 @@ func getAndSetMgmtSubnetAttributes(ctx context.Context, diags *diag.Diagnostics, if childAttributeName == "value" { TagTagMgmtSubnet.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagTagMgmtSubnet.Key.IsUnknown() { - TagTagMgmtSubnet.Key = types.StringNull() - } - if TagTagMgmtSubnet.Value.IsUnknown() { - TagTagMgmtSubnet.Value = types.StringNull() + } TagTagMgmtSubnetList = append(TagTagMgmtSubnetList, TagTagMgmtSubnet) } @@ -512,14 +521,7 @@ func setMgmtSubnetId(ctx context.Context, data *MgmtSubnetResourceModel) { } func getMgmtSubnetTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtSubnetResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} @@ -544,12 +546,10 @@ func getMgmtSubnetTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -560,14 +560,7 @@ func getMgmtSubnetTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di } func getMgmtSubnetTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagTagPlan, tagTagState []TagTagMgmtSubnetResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} @@ -592,12 +585,10 @@ func getMgmtSubnetTagTagChildPayloads(ctx context.Context, diags *diag.Diagnosti } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { diff --git a/internal/provider/resource_aci_l3out_consumer_label.go b/internal/provider/resource_aci_l3out_consumer_label.go index eb4045a46..6a2188e02 100644 --- a/internal/provider/resource_aci_l3out_consumer_label.go +++ b/internal/provider/resource_aci_l3out_consumer_label.go @@ -14,6 +14,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -63,12 +64,32 @@ type TagAnnotationL3extConsLblResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationL3extConsLblResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagAnnotationL3extConsLblResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationL3extConsLblResourceModelAttributeTypes()) +} + // TagTagL3extConsLblResourceModel describes the resource data model for the children without relation ships. type TagTagL3extConsLblResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagL3extConsLblResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagTagL3extConsLblResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagL3extConsLblResourceModelAttributeTypes()) +} + type L3extConsLblIdentifier struct { Name types.String } @@ -186,7 +207,6 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -215,7 +235,6 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -411,7 +430,7 @@ func (r *L3extConsLblResource) ImportState(ctx context.Context, req resource.Imp } func getAndSetL3extConsLblAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *L3extConsLblResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "l3extConsLbl,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -474,7 +493,9 @@ func getAndSetL3extConsLblAttributes(ctx context.Context, diags *diag.Diagnostic if data.Tag.IsUnknown() { data.Tag = types.StringNull() } + TagAnnotationL3extConsLbl := TagAnnotationL3extConsLblResourceModel{} TagAnnotationL3extConsLblList := make([]TagAnnotationL3extConsLblResourceModel, 0) + TagTagL3extConsLbl := TagTagL3extConsLblResourceModel{} TagTagL3extConsLblList := make([]TagTagL3extConsLblResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -483,7 +504,6 @@ func getAndSetL3extConsLblAttributes(ctx context.Context, diags *diag.Diagnostic for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "tagAnnotation" { - TagAnnotationL3extConsLbl := TagAnnotationL3extConsLblResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationL3extConsLbl.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -491,17 +511,11 @@ func getAndSetL3extConsLblAttributes(ctx context.Context, diags *diag.Diagnostic if childAttributeName == "value" { TagAnnotationL3extConsLbl.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagAnnotationL3extConsLbl.Key.IsUnknown() { - TagAnnotationL3extConsLbl.Key = types.StringNull() - } - if TagAnnotationL3extConsLbl.Value.IsUnknown() { - TagAnnotationL3extConsLbl.Value = types.StringNull() + } TagAnnotationL3extConsLblList = append(TagAnnotationL3extConsLblList, TagAnnotationL3extConsLbl) } if childClassName == "tagTag" { - TagTagL3extConsLbl := TagTagL3extConsLblResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagL3extConsLbl.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -509,12 +523,7 @@ func getAndSetL3extConsLblAttributes(ctx context.Context, diags *diag.Diagnostic if childAttributeName == "value" { TagTagL3extConsLbl.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagTagL3extConsLbl.Key.IsUnknown() { - TagTagL3extConsLbl.Key = types.StringNull() - } - if TagTagL3extConsLbl.Value.IsUnknown() { - TagTagL3extConsLbl.Value = types.StringNull() + } TagTagL3extConsLblList = append(TagTagL3extConsLblList, TagTagL3extConsLbl) } @@ -568,14 +577,7 @@ func setL3extConsLblId(ctx context.Context, data *L3extConsLblResourceModel) { } func getL3extConsLblTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extConsLblResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} @@ -600,12 +602,10 @@ func getL3extConsLblTagAnnotationChildPayloads(ctx context.Context, diags *diag. } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -616,14 +616,7 @@ func getL3extConsLblTagAnnotationChildPayloads(ctx context.Context, diags *diag. } func getL3extConsLblTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagTagPlan, tagTagState []TagTagL3extConsLblResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} @@ -648,12 +641,10 @@ func getL3extConsLblTagTagChildPayloads(ctx context.Context, diags *diag.Diagnos } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { diff --git a/internal/provider/resource_aci_l3out_redistribute_policy.go b/internal/provider/resource_aci_l3out_redistribute_policy.go index 641058aaa..136de9095 100644 --- a/internal/provider/resource_aci_l3out_redistribute_policy.go +++ b/internal/provider/resource_aci_l3out_redistribute_policy.go @@ -14,6 +14,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -58,12 +59,32 @@ type TagAnnotationL3extRsRedistributePolResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationL3extRsRedistributePolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagAnnotationL3extRsRedistributePolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationL3extRsRedistributePolResourceModelAttributeTypes()) +} + // TagTagL3extRsRedistributePolResourceModel describes the resource data model for the children without relation ships. type TagTagL3extRsRedistributePolResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagL3extRsRedistributePolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagTagL3extRsRedistributePolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagL3extRsRedistributePolResourceModelAttributeTypes()) +} + type L3extRsRedistributePolIdentifier struct { Src types.String TnRtctrlProfileName types.String @@ -134,7 +155,6 @@ func (r *L3extRsRedistributePolResource) Schema(ctx context.Context, req resourc Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -163,7 +183,6 @@ func (r *L3extRsRedistributePolResource) Schema(ctx context.Context, req resourc Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -359,7 +378,7 @@ func (r *L3extRsRedistributePolResource) ImportState(ctx context.Context, req re } func getAndSetL3extRsRedistributePolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *L3extRsRedistributePolResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "l3extRsRedistributePol,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -392,7 +411,9 @@ func getAndSetL3extRsRedistributePolAttributes(ctx context.Context, diags *diag. if data.TnRtctrlProfileName.IsUnknown() { data.TnRtctrlProfileName = types.StringNull() } + TagAnnotationL3extRsRedistributePol := TagAnnotationL3extRsRedistributePolResourceModel{} TagAnnotationL3extRsRedistributePolList := make([]TagAnnotationL3extRsRedistributePolResourceModel, 0) + TagTagL3extRsRedistributePol := TagTagL3extRsRedistributePolResourceModel{} TagTagL3extRsRedistributePolList := make([]TagTagL3extRsRedistributePolResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -401,7 +422,6 @@ func getAndSetL3extRsRedistributePolAttributes(ctx context.Context, diags *diag. for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "tagAnnotation" { - TagAnnotationL3extRsRedistributePol := TagAnnotationL3extRsRedistributePolResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationL3extRsRedistributePol.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -409,17 +429,11 @@ func getAndSetL3extRsRedistributePolAttributes(ctx context.Context, diags *diag. if childAttributeName == "value" { TagAnnotationL3extRsRedistributePol.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagAnnotationL3extRsRedistributePol.Key.IsUnknown() { - TagAnnotationL3extRsRedistributePol.Key = types.StringNull() - } - if TagAnnotationL3extRsRedistributePol.Value.IsUnknown() { - TagAnnotationL3extRsRedistributePol.Value = types.StringNull() + } TagAnnotationL3extRsRedistributePolList = append(TagAnnotationL3extRsRedistributePolList, TagAnnotationL3extRsRedistributePol) } if childClassName == "tagTag" { - TagTagL3extRsRedistributePol := TagTagL3extRsRedistributePolResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagL3extRsRedistributePol.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -427,12 +441,7 @@ func getAndSetL3extRsRedistributePolAttributes(ctx context.Context, diags *diag. if childAttributeName == "value" { TagTagL3extRsRedistributePol.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagTagL3extRsRedistributePol.Key.IsUnknown() { - TagTagL3extRsRedistributePol.Key = types.StringNull() - } - if TagTagL3extRsRedistributePol.Value.IsUnknown() { - TagTagL3extRsRedistributePol.Value = types.StringNull() + } TagTagL3extRsRedistributePolList = append(TagTagL3extRsRedistributePolList, TagTagL3extRsRedistributePol) } @@ -486,14 +495,7 @@ func setL3extRsRedistributePolId(ctx context.Context, data *L3extRsRedistributeP } func getL3extRsRedistributePolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsRedistributePolResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} @@ -518,12 +520,10 @@ func getL3extRsRedistributePolTagAnnotationChildPayloads(ctx context.Context, di } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -534,14 +534,7 @@ func getL3extRsRedistributePolTagAnnotationChildPayloads(ctx context.Context, di } func getL3extRsRedistributePolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagTagPlan, tagTagState []TagTagL3extRsRedistributePolResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} @@ -566,12 +559,10 @@ func getL3extRsRedistributePolTagTagChildPayloads(ctx context.Context, diags *di } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { diff --git a/internal/provider/resource_aci_out_of_band_contract.go b/internal/provider/resource_aci_out_of_band_contract.go index ba82ad93e..288c8da4c 100644 --- a/internal/provider/resource_aci_out_of_band_contract.go +++ b/internal/provider/resource_aci_out_of_band_contract.go @@ -14,6 +14,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -64,12 +65,32 @@ type TagAnnotationVzOOBBrCPResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationVzOOBBrCPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagAnnotationVzOOBBrCPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationVzOOBBrCPResourceModelAttributeTypes()) +} + // TagTagVzOOBBrCPResourceModel describes the resource data model for the children without relation ships. type TagTagVzOOBBrCPResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagVzOOBBrCPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagTagVzOOBBrCPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagVzOOBBrCPResourceModelAttributeTypes()) +} + type VzOOBBrCPIdentifier struct { Name types.String } @@ -203,7 +224,6 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -232,7 +252,6 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -428,7 +447,7 @@ func (r *VzOOBBrCPResource) ImportState(ctx context.Context, req resource.Import } func getAndSetVzOOBBrCPAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *VzOOBBrCPResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "vzOOBBrCP,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -502,7 +521,9 @@ func getAndSetVzOOBBrCPAttributes(ctx context.Context, diags *diag.Diagnostics, if data.TargetDscp.IsUnknown() { data.TargetDscp = types.StringNull() } + TagAnnotationVzOOBBrCP := TagAnnotationVzOOBBrCPResourceModel{} TagAnnotationVzOOBBrCPList := make([]TagAnnotationVzOOBBrCPResourceModel, 0) + TagTagVzOOBBrCP := TagTagVzOOBBrCPResourceModel{} TagTagVzOOBBrCPList := make([]TagTagVzOOBBrCPResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -511,7 +532,6 @@ func getAndSetVzOOBBrCPAttributes(ctx context.Context, diags *diag.Diagnostics, for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "tagAnnotation" { - TagAnnotationVzOOBBrCP := TagAnnotationVzOOBBrCPResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationVzOOBBrCP.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -519,17 +539,11 @@ func getAndSetVzOOBBrCPAttributes(ctx context.Context, diags *diag.Diagnostics, if childAttributeName == "value" { TagAnnotationVzOOBBrCP.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagAnnotationVzOOBBrCP.Key.IsUnknown() { - TagAnnotationVzOOBBrCP.Key = types.StringNull() - } - if TagAnnotationVzOOBBrCP.Value.IsUnknown() { - TagAnnotationVzOOBBrCP.Value = types.StringNull() + } TagAnnotationVzOOBBrCPList = append(TagAnnotationVzOOBBrCPList, TagAnnotationVzOOBBrCP) } if childClassName == "tagTag" { - TagTagVzOOBBrCP := TagTagVzOOBBrCPResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagVzOOBBrCP.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -537,12 +551,7 @@ func getAndSetVzOOBBrCPAttributes(ctx context.Context, diags *diag.Diagnostics, if childAttributeName == "value" { TagTagVzOOBBrCP.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagTagVzOOBBrCP.Key.IsUnknown() { - TagTagVzOOBBrCP.Key = types.StringNull() - } - if TagTagVzOOBBrCP.Value.IsUnknown() { - TagTagVzOOBBrCP.Value = types.StringNull() + } TagTagVzOOBBrCPList = append(TagTagVzOOBBrCPList, TagTagVzOOBBrCP) } @@ -580,14 +589,7 @@ func setVzOOBBrCPId(ctx context.Context, data *VzOOBBrCPResourceModel) { } func getVzOOBBrCPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationVzOOBBrCPResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} @@ -612,12 +614,10 @@ func getVzOOBBrCPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -628,14 +628,7 @@ func getVzOOBBrCPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } func getVzOOBBrCPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagTagPlan, tagTagState []TagTagVzOOBBrCPResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} @@ -660,12 +653,10 @@ func getVzOOBBrCPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostic } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { diff --git a/internal/provider/resource_aci_pim_route_map_entry.go b/internal/provider/resource_aci_pim_route_map_entry.go index bf845aeb5..c8fadb70c 100644 --- a/internal/provider/resource_aci_pim_route_map_entry.go +++ b/internal/provider/resource_aci_pim_route_map_entry.go @@ -14,6 +14,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -64,12 +65,32 @@ type TagAnnotationPimRouteMapEntryResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationPimRouteMapEntryResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagAnnotationPimRouteMapEntryResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationPimRouteMapEntryResourceModelAttributeTypes()) +} + // TagTagPimRouteMapEntryResourceModel describes the resource data model for the children without relation ships. type TagTagPimRouteMapEntryResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagPimRouteMapEntryResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagTagPimRouteMapEntryResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagPimRouteMapEntryResourceModelAttributeTypes()) +} + type PimRouteMapEntryIdentifier struct { Order types.String } @@ -193,7 +214,6 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -222,7 +242,6 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -418,7 +437,7 @@ func (r *PimRouteMapEntryResource) ImportState(ctx context.Context, req resource } func getAndSetPimRouteMapEntryAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *PimRouteMapEntryResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "pimRouteMapEntry,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -487,7 +506,9 @@ func getAndSetPimRouteMapEntryAttributes(ctx context.Context, diags *diag.Diagno if data.Src.IsUnknown() { data.Src = types.StringNull() } + TagAnnotationPimRouteMapEntry := TagAnnotationPimRouteMapEntryResourceModel{} TagAnnotationPimRouteMapEntryList := make([]TagAnnotationPimRouteMapEntryResourceModel, 0) + TagTagPimRouteMapEntry := TagTagPimRouteMapEntryResourceModel{} TagTagPimRouteMapEntryList := make([]TagTagPimRouteMapEntryResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -496,7 +517,6 @@ func getAndSetPimRouteMapEntryAttributes(ctx context.Context, diags *diag.Diagno for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "tagAnnotation" { - TagAnnotationPimRouteMapEntry := TagAnnotationPimRouteMapEntryResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationPimRouteMapEntry.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -504,17 +524,11 @@ func getAndSetPimRouteMapEntryAttributes(ctx context.Context, diags *diag.Diagno if childAttributeName == "value" { TagAnnotationPimRouteMapEntry.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagAnnotationPimRouteMapEntry.Key.IsUnknown() { - TagAnnotationPimRouteMapEntry.Key = types.StringNull() - } - if TagAnnotationPimRouteMapEntry.Value.IsUnknown() { - TagAnnotationPimRouteMapEntry.Value = types.StringNull() + } TagAnnotationPimRouteMapEntryList = append(TagAnnotationPimRouteMapEntryList, TagAnnotationPimRouteMapEntry) } if childClassName == "tagTag" { - TagTagPimRouteMapEntry := TagTagPimRouteMapEntryResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagPimRouteMapEntry.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -522,12 +536,7 @@ func getAndSetPimRouteMapEntryAttributes(ctx context.Context, diags *diag.Diagno if childAttributeName == "value" { TagTagPimRouteMapEntry.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagTagPimRouteMapEntry.Key.IsUnknown() { - TagTagPimRouteMapEntry.Key = types.StringNull() - } - if TagTagPimRouteMapEntry.Value.IsUnknown() { - TagTagPimRouteMapEntry.Value = types.StringNull() + } TagTagPimRouteMapEntryList = append(TagTagPimRouteMapEntryList, TagTagPimRouteMapEntry) } @@ -581,14 +590,7 @@ func setPimRouteMapEntryId(ctx context.Context, data *PimRouteMapEntryResourceMo } func getPimRouteMapEntryTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapEntryResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} @@ -613,12 +615,10 @@ func getPimRouteMapEntryTagAnnotationChildPayloads(ctx context.Context, diags *d } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -629,14 +629,7 @@ func getPimRouteMapEntryTagAnnotationChildPayloads(ctx context.Context, diags *d } func getPimRouteMapEntryTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagTagPlan, tagTagState []TagTagPimRouteMapEntryResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} @@ -661,12 +654,10 @@ func getPimRouteMapEntryTagTagChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { diff --git a/internal/provider/resource_aci_pim_route_map_policy.go b/internal/provider/resource_aci_pim_route_map_policy.go index 05a7c78fe..8818bda4f 100644 --- a/internal/provider/resource_aci_pim_route_map_policy.go +++ b/internal/provider/resource_aci_pim_route_map_policy.go @@ -13,6 +13,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -59,12 +60,32 @@ type TagAnnotationPimRouteMapPolResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationPimRouteMapPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagAnnotationPimRouteMapPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationPimRouteMapPolResourceModelAttributeTypes()) +} + // TagTagPimRouteMapPolResourceModel describes the resource data model for the children without relation ships. type TagTagPimRouteMapPolResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagPimRouteMapPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagTagPimRouteMapPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagPimRouteMapPolResourceModelAttributeTypes()) +} + type PimRouteMapPolIdentifier struct { Name types.String } @@ -158,7 +179,6 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -187,7 +207,6 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -383,7 +402,7 @@ func (r *PimRouteMapPolResource) ImportState(ctx context.Context, req resource.I } func getAndSetPimRouteMapPolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *PimRouteMapPolResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "pimRouteMapPol,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -434,7 +453,9 @@ func getAndSetPimRouteMapPolAttributes(ctx context.Context, diags *diag.Diagnost if data.OwnerTag.IsUnknown() { data.OwnerTag = types.StringNull() } + TagAnnotationPimRouteMapPol := TagAnnotationPimRouteMapPolResourceModel{} TagAnnotationPimRouteMapPolList := make([]TagAnnotationPimRouteMapPolResourceModel, 0) + TagTagPimRouteMapPol := TagTagPimRouteMapPolResourceModel{} TagTagPimRouteMapPolList := make([]TagTagPimRouteMapPolResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -443,7 +464,6 @@ func getAndSetPimRouteMapPolAttributes(ctx context.Context, diags *diag.Diagnost for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "tagAnnotation" { - TagAnnotationPimRouteMapPol := TagAnnotationPimRouteMapPolResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationPimRouteMapPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -451,17 +471,11 @@ func getAndSetPimRouteMapPolAttributes(ctx context.Context, diags *diag.Diagnost if childAttributeName == "value" { TagAnnotationPimRouteMapPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagAnnotationPimRouteMapPol.Key.IsUnknown() { - TagAnnotationPimRouteMapPol.Key = types.StringNull() - } - if TagAnnotationPimRouteMapPol.Value.IsUnknown() { - TagAnnotationPimRouteMapPol.Value = types.StringNull() + } TagAnnotationPimRouteMapPolList = append(TagAnnotationPimRouteMapPolList, TagAnnotationPimRouteMapPol) } if childClassName == "tagTag" { - TagTagPimRouteMapPol := TagTagPimRouteMapPolResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagPimRouteMapPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -469,12 +483,7 @@ func getAndSetPimRouteMapPolAttributes(ctx context.Context, diags *diag.Diagnost if childAttributeName == "value" { TagTagPimRouteMapPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagTagPimRouteMapPol.Key.IsUnknown() { - TagTagPimRouteMapPol.Key = types.StringNull() - } - if TagTagPimRouteMapPol.Value.IsUnknown() { - TagTagPimRouteMapPol.Value = types.StringNull() + } TagTagPimRouteMapPolList = append(TagTagPimRouteMapPolList, TagTagPimRouteMapPol) } @@ -528,14 +537,7 @@ func setPimRouteMapPolId(ctx context.Context, data *PimRouteMapPolResourceModel) } func getPimRouteMapPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapPolResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} @@ -560,12 +562,10 @@ func getPimRouteMapPolTagAnnotationChildPayloads(ctx context.Context, diags *dia } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -576,14 +576,7 @@ func getPimRouteMapPolTagAnnotationChildPayloads(ctx context.Context, diags *dia } func getPimRouteMapPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagTagPlan, tagTagState []TagTagPimRouteMapPolResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} @@ -608,12 +601,10 @@ func getPimRouteMapPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagn } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { diff --git a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go index 67a94be36..9c94ffa9a 100644 --- a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go +++ b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go @@ -14,6 +14,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -58,12 +59,32 @@ type TagAnnotationMgmtRsOoBConsResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationMgmtRsOoBConsResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagAnnotationMgmtRsOoBConsResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtRsOoBConsResourceModelAttributeTypes()) +} + // TagTagMgmtRsOoBConsResourceModel describes the resource data model for the children without relation ships. type TagTagMgmtRsOoBConsResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagMgmtRsOoBConsResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} +func TagTagMgmtRsOoBConsResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtRsOoBConsResourceModelAttributeTypes()) +} + type MgmtRsOoBConsIdentifier struct { TnVzOOBBrCPName types.String } @@ -133,7 +154,6 @@ func (r *MgmtRsOoBConsResource) Schema(ctx context.Context, req resource.SchemaR Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -162,7 +182,6 @@ func (r *MgmtRsOoBConsResource) Schema(ctx context.Context, req resource.SchemaR Computed: true, PlanModifiers: []planmodifier.Set{ setplanmodifier.UseStateForUnknown(), - SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ @@ -358,7 +377,7 @@ func (r *MgmtRsOoBConsResource) ImportState(ctx context.Context, req resource.Im } func getAndSetMgmtRsOoBConsAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *MgmtRsOoBConsResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtRsOoBCons,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -391,7 +410,9 @@ func getAndSetMgmtRsOoBConsAttributes(ctx context.Context, diags *diag.Diagnosti if data.TnVzOOBBrCPName.IsUnknown() { data.TnVzOOBBrCPName = types.StringNull() } + TagAnnotationMgmtRsOoBCons := TagAnnotationMgmtRsOoBConsResourceModel{} TagAnnotationMgmtRsOoBConsList := make([]TagAnnotationMgmtRsOoBConsResourceModel, 0) + TagTagMgmtRsOoBCons := TagTagMgmtRsOoBConsResourceModel{} TagTagMgmtRsOoBConsList := make([]TagTagMgmtRsOoBConsResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -400,7 +421,6 @@ func getAndSetMgmtRsOoBConsAttributes(ctx context.Context, diags *diag.Diagnosti for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "tagAnnotation" { - TagAnnotationMgmtRsOoBCons := TagAnnotationMgmtRsOoBConsResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationMgmtRsOoBCons.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -408,17 +428,11 @@ func getAndSetMgmtRsOoBConsAttributes(ctx context.Context, diags *diag.Diagnosti if childAttributeName == "value" { TagAnnotationMgmtRsOoBCons.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagAnnotationMgmtRsOoBCons.Key.IsUnknown() { - TagAnnotationMgmtRsOoBCons.Key = types.StringNull() - } - if TagAnnotationMgmtRsOoBCons.Value.IsUnknown() { - TagAnnotationMgmtRsOoBCons.Value = types.StringNull() + } TagAnnotationMgmtRsOoBConsList = append(TagAnnotationMgmtRsOoBConsList, TagAnnotationMgmtRsOoBCons) } if childClassName == "tagTag" { - TagTagMgmtRsOoBCons := TagTagMgmtRsOoBConsResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagMgmtRsOoBCons.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -426,12 +440,7 @@ func getAndSetMgmtRsOoBConsAttributes(ctx context.Context, diags *diag.Diagnosti if childAttributeName == "value" { TagTagMgmtRsOoBCons.Value = basetypes.NewStringValue(childAttributeValue.(string)) } - } - if TagTagMgmtRsOoBCons.Key.IsUnknown() { - TagTagMgmtRsOoBCons.Key = types.StringNull() - } - if TagTagMgmtRsOoBCons.Value.IsUnknown() { - TagTagMgmtRsOoBCons.Value = types.StringNull() + } TagTagMgmtRsOoBConsList = append(TagTagMgmtRsOoBConsList, TagTagMgmtRsOoBCons) } @@ -485,14 +494,7 @@ func setMgmtRsOoBConsId(ctx context.Context, data *MgmtRsOoBConsResourceModel) { } func getMgmtRsOoBConsTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtRsOoBConsResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} @@ -517,12 +519,10 @@ func getMgmtRsOoBConsTagAnnotationChildPayloads(ctx context.Context, diags *diag } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -533,14 +533,7 @@ func getMgmtRsOoBConsTagAnnotationChildPayloads(ctx context.Context, diags *diag } func getMgmtRsOoBConsTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagTagPlan, tagTagState []TagTagMgmtRsOoBConsResourceModel) []map[string]interface{} { - type childMapType struct { - Attributes map[string]interface{} `json:"attributes"` - Children []map[string]interface{} `json:"children"` - } - childMap := childMapType{ - Attributes: make(map[string]interface{}), - Children: make([]map[string]interface{}, 0), - } + childMap := newAciObjectType() childPayloads := []map[string]interface{}{} if !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} @@ -565,12 +558,10 @@ func getMgmtRsOoBConsTagTagChildPayloads(ctx context.Context, diags *diag.Diagno } } if delete { - childMap := childMapType{ - Attributes: make(map[string]interface{}), - } - childMap.Attributes["status"] = "deleted" - childMap.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { diff --git a/internal/provider/utils.go b/internal/provider/utils.go index 273029609..41e99603a 100644 --- a/internal/provider/utils.go +++ b/internal/provider/utils.go @@ -3,9 +3,7 @@ package provider import ( "context" "fmt" - "log" "net/http" - "reflect" "strings" "github.com/ciscoecosystem/aci-go-client/v2/client" @@ -14,10 +12,21 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-log/tflog" ) +type aciObjectType struct { + Attributes map[string]interface{} `json:"attributes"` + Children []map[string]interface{} `json:"children"` +} + +func newAciObjectType() aciObjectType { + return aciObjectType{ + Attributes: make(map[string]interface{}), + Children: []map[string]interface{}{}, + } +} + func ContainsString(strings []string, matchString string) bool { for _, stringValue := range strings { if stringValue == matchString { @@ -131,91 +140,3 @@ func (m setToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate) PlanModifyStrin } return } - -// type setToUnknownWhenStateIsNullPlanIsUnknownDuringUpdate struct{} - -// func SetToUnknownWhenStateIsNullPlanIsUnknownDuringUpdate() planmodifier.String { -// return setToUnknownWhenStateIsNullPlanIsUnknownDuringUpdate{} -// } - -// func (m setToUnknownWhenStateIsNullPlanIsUnknownDuringUpdate) Description(_ context.Context) string { -// return "During the update phase, set the value of this attribute to StringNull when the state value is null and the plan value is unknown." -// } - -// func (m setToUnknownWhenStateIsNullPlanIsUnknownDuringUpdate) MarkdownDescription(_ context.Context) string { -// return "During the update phase, set the value of this attribute to StringNull when the state value is null and the plan value is unknown." -// } - -// // Custom plan modifier to set the plan value to null under certain conditions -// func (m setToUnknownWhenStateIsNullPlanIsUnknownDuringUpdate) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { -// // Set the plan value to StringType null when state value is null and plan value is unknown during an Update -// if !req.State.Raw.IsNull() && req.StateValue.IsNull() && req.PlanValue.IsNull() { -// resp.PlanValue = types.StringUnknown() -// } -// return -// } - -type setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate struct{} - -func SetToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate() planmodifier.Set { - return setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate{} -} - -func (m setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate) Description(_ context.Context) string { - return "During the update phase, set the value of this attribute to SetNull when the state value is null and the plan value is unknown." -} - -func (m setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate) MarkdownDescription(_ context.Context) string { - return "During the update phase, set the value of this attribute to SetNull when the state value is null and the plan value is unknown." -} - -// Custom plan modifier to set the plan value to null under certain conditions -func (m setToSetNullWhenStateIsNullPlanIsUnknownDuringUpdate) PlanModifySet(ctx context.Context, req planmodifier.SetRequest, resp *planmodifier.SetResponse) { - // Set the plan value to SetType null when state value is null and plan value is unknown during an Update - log.Printf("hereStateval %v", req.StateValue) - log.Printf("hereStatevalIsUnknown %v", req.StateValue.IsUnknown()) - log.Printf("hereStatevalIsNull %v", req.StateValue.IsNull()) - log.Printf("herePlanval %v", req.PlanValue) - log.Printf("herePlanvalIsUnknown %v", req.PlanValue.IsUnknown()) - log.Printf("herePlanvalIsNull %v", req.PlanValue.IsNull()) - - // log.Printf("hereType %v %v", idx, element.Type(ctx)) - // } - // if !req.State.Raw.IsNull() && req.PlanValue.Equal(req.StateValue) && req.ConfigValue.IsNull(){ - // resp.PlanValue = types.SetNull(req.PlanValue.ElementType(ctx)) - // } - - // if !req.State.Raw.IsNull() && req.StateValue.IsNull() && req.PlanValue.IsUnknown() { - // //log.Printf("hereStateval %v;hereStateIsUnknown %v; hereStateIsNull %v;herePlanVal %v, herePlanIsUnknown %v, herePlanIsNull %v, hereConfigVal %v, hereConfisIsUnkown %v, hereConfigIsNull %v", req.StateValue, req.StateValue.IsUnknown(), req.StateValue.IsNull(), req.PlanValue, req.PlanValue.IsUnknown(), req.PlanValue.IsNull(), req.ConfigValue, req.ConfigValue.IsUnknown(), req.ConfigValue.IsNull()) - // resp.PlanValue = types.SetNull(req.PlanValue.ElementType(ctx)) - // } - return -} - -func areAllStringFieldsEmpty(v interface{}) bool { - val := reflect.ValueOf(v) - - // Check if the passed interface is a struct - if val.Kind() != reflect.Struct { - return false - } - - // Iterate over all fields in the struct - for i := 0; i < val.NumField(); i++ { - field := val.Field(i) - fieldType := field.Type() - - // Check if the field is of type basestring - if fieldType != reflect.TypeOf(basetypes.NewStringValue("")) { - return false - } - - // Check if the string is not empty - if !field.IsZero() { - return false - } - } - - // All string fields are empty - return true -} From b3fa0daf0ef93b87ca833f2960c9989c50223e7f Mon Sep 17 00:00:00 2001 From: Shreyas Date: Tue, 23 Apr 2024 06:08:22 -0400 Subject: [PATCH 07/20] [ignore] Made changes to resource template to include child attributes in the child payload only when defined in the config --- gen/templates/resource.go.tmpl | 70 ++++----- .../resource_aci_communication_policy.go | 144 +++++++++--------- .../provider/resource_aci_endpoint_tag_ip.go | 22 +-- .../provider/resource_aci_endpoint_tag_mac.go | 22 +-- ...nal_management_network_instance_profile.go | 35 +++-- ..._aci_external_management_network_subnet.go | 22 +-- .../resource_aci_l3out_consumer_label.go | 22 +-- .../resource_aci_l3out_redistribute_policy.go | 22 +-- .../resource_aci_out_of_band_contract.go | 22 +-- .../resource_aci_pim_route_map_entry.go | 22 +-- .../resource_aci_pim_route_map_policy.go | 22 +-- ...lation_to_consumed_out_of_band_contract.go | 22 +-- internal/provider/utils.go | 6 +- 13 files changed, 234 insertions(+), 219 deletions(-) diff --git a/gen/templates/resource.go.tmpl b/gen/templates/resource.go.tmpl index d7cba76db..578373653 100644 --- a/gen/templates/resource.go.tmpl +++ b/gen/templates/resource.go.tmpl @@ -497,16 +497,15 @@ func getAndSet{{.ResourceClassName}}Attributes(ctx context.Context, diags *diag. {{- end}} {{- end}} {{- end}} - {{/* $enteredGrandChildGetAndSetAttributesZone is used here because the presence of grand children is unknown while rendering the template unlike .HasChild used for the immediate children. It is also used because there can be more than one grandchild in the same level*/}} + {{/* $enteredGrandChildGetAndSetAttributesZone is used here because the presence of grand children is unknown while rendering the template unlike .HasChild used for the immediate children. It is also used because there can be more than one grandchild in the same level. */}} {{- $enteredGrandChildGetAndSetAttributesZone := false }} {{- range .Children}} {{- if not $enteredGrandChildGetAndSetAttributesZone }} {{- $enteredGrandChildGetAndSetAttributesZone = true }} } - _, childrenOf{{.ParentName}}Exist:= childClassDetails.(map[string]interface{})["children"] + childrenOf{{.ParentName}}, childrenOf{{.ParentName}}Exist:= childClassDetails.(map[string]interface{})["children"] if childrenOf{{.ParentName}}Exist { - childClassesOf{{.ParentName}} := childClassDetails.(map[string]interface{})["children"].([]interface{}) - for _, child{{.ParentName}} := range childClassesOf{{.ParentName}} { + for _, child{{.ParentName}} := range childrenOf{{.ParentName}}.([]interface{}) { for childClassName{{.ParentName}}, childClassDetails{{.ParentName}} := range child{{.ParentName}}.(map[string]interface{}) { {{- end}} {{- template "getAndSetGrandChildren" . }} @@ -516,12 +515,8 @@ func getAndSet{{.ResourceClassName}}Attributes(ctx context.Context, diags *diag. } } {{- range .Children}} - if len({{.ResourceClassName}}{{.ParentName}}List) > 0 { {{.ResourceClassName}}Set,_:=types.SetValueFrom(ctx,{{.ResourceClassName}}{{.ParentName}}ResourceModelElementType(),{{.ResourceClassName}}{{.ParentName}}List) {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}}={{.ResourceClassName}}Set - } else{ - {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}}=types.SetNull({{.ResourceClassName}}{{.ParentName}}ResourceModelElementType()) - } {{- end}} {{- else}} } @@ -598,7 +593,7 @@ func set{{.ResourceClassName}}Id(ctx context.Context, data *{{.ResourceClassName {{ range .Children}} func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *{{$.ResourceClassName}}ResourceModel, {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} {{- $enteredGrandChildDeclarationZone := false }} {{- range .Children}} @@ -611,13 +606,13 @@ func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context {{.ParentName}}Children := make([]map[string]interface{}, 0) {{- end}} {{- end}} - if !data.{{.ResourceClassName}}.IsUnknown() { + if !data.{{.ResourceClassName}}.IsNull() && !data.{{.ResourceClassName}}.IsUnknown() { {{- if .IdentifiedBy}} {{ .PkgName }}Identifiers := []{{.ResourceClassName}}Identifier{} {{- end}} for _, {{ .PkgName }} := range {{ .PkgName }}Plan { {{- range .Properties}} - if !{{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsUnknown(){ + if !{{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsNull() && !{{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsUnknown(){ {{- if eq .ValueType "bitmask"}} var tmp{{ .Name }} []string {{ .PkgName }}.{{ .Name }}.ElementsAs(ctx, &tmp{{ .Name }}, false) @@ -668,7 +663,7 @@ func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context } } if delete { - {{.PkgName}}ChildMapForDelete := newAciObjectType() + {{.PkgName}}ChildMapForDelete := NewAciObject() {{.PkgName}}ChildMapForDelete.Attributes["status"] = "deleted" {{- range .Properties}} {{- if .IsNaming }} @@ -681,7 +676,7 @@ func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context {{- else}} if len({{ .PkgName }}Plan) == 0 && len({{ .PkgName }}State) == 1 { {{- if .AllowDelete}} - {{.PkgName}}ChildMapForDelete := newAciObjectType() + {{.PkgName}}ChildMapForDelete := NewAciObject() {{.PkgName}}ChildMapForDelete.Attributes["status"] = "deleted" childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": {{.PkgName}}ChildMapForDelete}) {{- else}} @@ -752,6 +747,9 @@ func get{{.ResourceClassName}}CreateJsonPayload(ctx context.Context, diags *diag return jsonPayload } + +{{/* Sub Templates */}} + {{/* A sub template for the child structs used in the structs definiton section. */}} {{- define "childStructsAndAttributeTypes" }} // {{.ResourceClassName}}{{.ParentName}}ResourceModel describes the resource data model for the children without relation ships. @@ -769,6 +767,7 @@ type {{.ResourceClassName}}{{.ParentName}}ResourceModel struct { {{ .ResourceClassName }} types.Set `tfsdk:"{{- .ResourceName}}"` {{- end}} } + func {{.ResourceClassName}}{{.ParentName}}ResourceModelAttributeTypes() map[string]attr.Type { return map[string]attr.Type{ {{- range .Properties}} @@ -785,6 +784,7 @@ func {{.ResourceClassName}}{{.ParentName}}ResourceModelAttributeTypes() map[stri {{- end}} } } + func {{.ResourceClassName}}{{.ParentName}}ResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{},{{.ResourceClassName}}{{.ParentName}}ResourceModelAttributeTypes()) } @@ -793,6 +793,7 @@ func {{.ResourceClassName}}{{.ParentName}}ResourceModelElementType() attr.TypeWi {{- end}} {{- end}} + {{/* A sub template for the child attributes used in the Attributes block. */}} {{- define "childAttributes" }} "{{- .ResourceName }}": schema.SetNestedAttribute{ @@ -857,14 +858,16 @@ func {{.ResourceClassName}}{{.ParentName}}ResourceModelElementType() attr.TypeWi {{- end }} {{- end }} + {{/* A sub template for the grand child attributes used in the Payload function. */}} {{- define "grandChildPayload" }} -var {{.PkgName}}Plan []{{.ResourceClassName}}{{.ParentName}}ResourceModel +var {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{.ParentName}}ResourceModel {{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}Plan, false) -for _, {{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}} := range {{.ParentName | lowerFirstCharacter}}State { -if len({{ .PkgName }}Plan) == 0 && len({{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}}.{{.ResourceClassName}}.Elements()) == 1 { +for _, {{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}}State := range {{.ParentName | lowerFirstCharacter}}State { +{{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}}State.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}State, false) +if len({{ .PkgName }}Plan) == 0 && len({{.PkgName}}State) == 1 { {{- if .AllowDelete}} - {{.PkgName}}ChildMap := newAciObjectType() + {{.PkgName}}ChildMap := NewAciObject() {{.PkgName}}ChildMap.Attributes["status"] = "deleted" {{ .ParentName }}Children = append({{ .ParentName }}Children, map[string]interface{}{"{{.PkgName}}": {{.PkgName}}ChildMap}) {{- else}} @@ -876,10 +879,10 @@ if len({{ .PkgName }}Plan) == 0 && len({{.ParentName | lowerFirstCharacter}}{{.R {{- end }} } } -if !{{ .ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.IsUnknown(){ +if !{{ .ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.IsNull() && !{{ .ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.IsUnknown(){ for _, {{ .PkgName }} := range {{.PkgName}}Plan { {{- range .Properties}} - if !{{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsUnknown(){ + if !{{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsNull() && !{{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsUnknown(){ {{- if eq .ValueType "bitmask"}} var tmp{{ .Name }} []string {{ .PkgName }}.{{ .Name }}.ElementsAs(ctx, &tmp{{ .Name }}, false) @@ -902,7 +905,7 @@ for _, {{ .PkgName }} := range {{.PkgName}}Plan { {{- end }} - +{{/* A sub template to declare child lists in the get and set attributes function. */}} {{- define "declareChildListsInGetandSetAttributesFunction" }} {{.ResourceClassName}}{{.ParentName}} := {{ .ResourceClassName}}{{.ParentName}}ResourceModel{} {{- if .IdentifiedBy}} @@ -916,6 +919,7 @@ for _, {{ .PkgName }} := range {{.PkgName}}Plan { {{- end}} +{{/* A sub template for the grand child attributes used in the get and set attributes function. */}} {{- define "getAndSetGrandChildren" }} if childClassName{{.ParentName}} == "{{.PkgName}}"{ {{.PkgName}}childAttributeValue:= childClassDetails{{.ParentName}}.(map[string]interface{})["attributes"].(map[string]interface{}) @@ -965,10 +969,9 @@ for childAttributeName, childAttributeValue := range {{.PkgName}}childAttributeV {{- if not $enteredGrandChildGetAndSetAttributesZone }} {{- $enteredGrandChildGetAndSetAttributesZone = true }} } - _, childrenOf{{.ParentName}}:= childClassDetails.(map[string]interface{})["children"] - if childrenOf{{.ParentName}} { - childClassesOf{{.ParentName}} := childClassDetails.(map[string]interface{})["children"].([]interface{}) - for _, child{{.ParentName}} := range childClassesOf{{.ParentName}} { + childrenOf{{.ParentName}}, childrenOf{{.ParentName}}Exist:= childClassDetails.(map[string]interface{})["children"] + if childrenOf{{.ParentName}}Exist { + for _, child{{.ParentName}} := range childrenOf{{.ParentName}}.([]interface{}) { for childClassName{{.ParentName}}, childClassDetails{{.ParentName}} := range child{{.ParentName}}.(map[string]interface{}) { {{- end}} {{- template "getAndSetGrandChildren" . }} @@ -978,12 +981,8 @@ for childAttributeName, childAttributeValue := range {{.PkgName}}childAttributeV } } {{- range .Children}} - if len({{.ResourceClassName}}{{.ParentName}}List) > 0 { {{.ResourceClassName}}Set,_:=types.SetValueFrom(ctx,{{.ResourceClassName}}{{.ParentName}}ResourceModelElementType(),{{.ResourceClassName}}{{.ParentName}}List) {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}}={{.ResourceClassName}}Set - } else{ - {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}}=types.SetNull({{.ResourceClassName}}{{.ParentName}}ResourceModelElementType()) - } {{- end}} {{- else}} } @@ -992,21 +991,25 @@ for childAttributeName, childAttributeValue := range {{.PkgName}}childAttributeV } {{- end }} + +{{/* A sub template for grand child declaration in the child payload function. */}} {{- define "grandChildDeclarationInChildPayloadFunction" }} -{{.PkgName}}ChildMap := newAciObjectType() +{{.PkgName}}ChildMap := NewAciObject() {{- $enteredGrandChildDeclarationZone := false }} {{- range .Children}} -{{- $enteredGrandChildDeclarationZone = true }} + {{- $enteredGrandChildDeclarationZone = true }} {{- template "grandChildDeclarationInChildPayloadFunction" . }} {{- end }} {{- range .Children}} -{{- if $enteredGrandChildDeclarationZone }} -{{- $enteredGrandChildDeclarationZone = false }} + {{- if $enteredGrandChildDeclarationZone }} + {{- $enteredGrandChildDeclarationZone = false }} {{.ParentName}}Children := make([]map[string]interface{}, 0) -{{- end}} + {{- end}} {{- end}} {{- end}} + +{{/* A sub template for joining all the class names as a single string. */}} {{- define "rspSubtreeClassFilter" -}} {{- $currentClasses := listToString .ChildClasses -}} {{- $currentClasses -}} @@ -1016,4 +1019,3 @@ for childAttributeName, childAttributeValue := range {{.PkgName}}childAttributeV {{- end -}} {{- end -}} {{- end -}} - diff --git a/internal/provider/resource_aci_communication_policy.go b/internal/provider/resource_aci_communication_policy.go index 11b7bf566..73303ad51 100644 --- a/internal/provider/resource_aci_communication_policy.go +++ b/internal/provider/resource_aci_communication_policy.go @@ -114,6 +114,7 @@ func CommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { "key_ring": types.SetType{ElemType: types.StringType}, } } + func CommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommHttpsCommPolResourceModelAttributeTypes()) } @@ -130,6 +131,7 @@ func CommRsClientCertCACommHttpsResourceModelAttributeTypes() map[string]attr.Ty "target_dn": types.StringType, } } + func CommRsClientCertCACommHttpsResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommRsClientCertCACommHttpsResourceModelAttributeTypes()) } @@ -146,6 +148,7 @@ func CommRsKeyRingCommHttpsResourceModelAttributeTypes() map[string]attr.Type { "tn_pki_key_ring_name": types.StringType, } } + func CommRsKeyRingCommHttpsResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommRsKeyRingCommHttpsResourceModelAttributeTypes()) } @@ -162,6 +165,7 @@ func TagAnnotationCommPolResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagAnnotationCommPolResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationCommPolResourceModelAttributeTypes()) } @@ -178,6 +182,7 @@ func TagTagCommPolResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagTagCommPolResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagCommPolResourceModelAttributeTypes()) } @@ -970,10 +975,9 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl } } - _, childrenOfCommHttpsExist := childClassDetails.(map[string]interface{})["children"] + childrenOfCommHttps, childrenOfCommHttpsExist := childClassDetails.(map[string]interface{})["children"] if childrenOfCommHttpsExist { - childClassesOfCommHttps := childClassDetails.(map[string]interface{})["children"].([]interface{}) - for _, childCommHttps := range childClassesOfCommHttps { + for _, childCommHttps := range childrenOfCommHttps.([]interface{}) { for childClassNameCommHttps, childClassDetailsCommHttps := range childCommHttps.(map[string]interface{}) { if childClassNameCommHttps == "commRsClientCertCA" { commRsClientCertCAchildAttributeValue := childClassDetailsCommHttps.(map[string]interface{})["attributes"].(map[string]interface{}) @@ -1002,18 +1006,10 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl } } } - if len(CommRsClientCertCACommHttpsList) > 0 { - CommRsClientCertCASet, _ := types.SetValueFrom(ctx, CommRsClientCertCACommHttpsResourceModelElementType(), CommRsClientCertCACommHttpsList) - CommHttpsCommPol.CommRsClientCertCA = CommRsClientCertCASet - } else { - CommHttpsCommPol.CommRsClientCertCA = types.SetNull(CommRsClientCertCACommHttpsResourceModelElementType()) - } - if len(CommRsKeyRingCommHttpsList) > 0 { - CommRsKeyRingSet, _ := types.SetValueFrom(ctx, CommRsKeyRingCommHttpsResourceModelElementType(), CommRsKeyRingCommHttpsList) - CommHttpsCommPol.CommRsKeyRing = CommRsKeyRingSet - } else { - CommHttpsCommPol.CommRsKeyRing = types.SetNull(CommRsKeyRingCommHttpsResourceModelElementType()) - } + CommRsClientCertCASet, _ := types.SetValueFrom(ctx, CommRsClientCertCACommHttpsResourceModelElementType(), CommRsClientCertCACommHttpsList) + CommHttpsCommPol.CommRsClientCertCA = CommRsClientCertCASet + CommRsKeyRingSet, _ := types.SetValueFrom(ctx, CommRsKeyRingCommHttpsResourceModelElementType(), CommRsKeyRingCommHttpsList) + CommHttpsCommPol.CommRsKeyRing = CommRsKeyRingSet CommHttpsCommPolList = append(CommHttpsCommPolList, CommHttpsCommPol) } if childClassName == "tagAnnotation" { @@ -1043,18 +1039,12 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl } } } - if len(CommHttpsCommPolList) > 0 { - commHttpsSet, _ := types.SetValueFrom(ctx, data.CommHttps.ElementType(ctx), CommHttpsCommPolList) - data.CommHttps = commHttpsSet - } - if len(TagAnnotationCommPolList) > 0 { - tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationCommPolList) - data.TagAnnotation = tagAnnotationSet - } - if len(TagTagCommPolList) > 0 { - tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagCommPolList) - data.TagTag = tagTagSet - } + commHttpsSet, _ := types.SetValueFrom(ctx, data.CommHttps.ElementType(ctx), CommHttpsCommPolList) + data.CommHttps = commHttpsSet + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationCommPolList) + data.TagAnnotation = tagAnnotationSet + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagCommPolList) + data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -1082,109 +1072,111 @@ func setCommPolId(ctx context.Context, data *CommPolResourceModel) { } func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, commHttpsPlan, commHttpsState []CommHttpsCommPolResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - commRsClientCertCAChildMap := newAciObjectType() - commRsKeyRingChildMap := newAciObjectType() + commRsClientCertCAChildMap := NewAciObject() + commRsKeyRingChildMap := NewAciObject() CommHttpsChildren := make([]map[string]interface{}, 0) - if !data.CommHttps.IsUnknown() { + if !data.CommHttps.IsNull() && !data.CommHttps.IsUnknown() { for _, commHttps := range commHttpsPlan { - if !commHttps.AccessControlAllowCredential.IsUnknown() { + if !commHttps.AccessControlAllowCredential.IsNull() && !commHttps.AccessControlAllowCredential.IsUnknown() { childMap.Attributes["accessControlAllowCredential"] = commHttps.AccessControlAllowCredential.ValueString() } - if !commHttps.AccessControlAllowOrigins.IsUnknown() { + if !commHttps.AccessControlAllowOrigins.IsNull() && !commHttps.AccessControlAllowOrigins.IsUnknown() { childMap.Attributes["accessControlAllowOrigins"] = commHttps.AccessControlAllowOrigins.ValueString() } - if !commHttps.AdminSt.IsUnknown() { + if !commHttps.AdminSt.IsNull() && !commHttps.AdminSt.IsUnknown() { childMap.Attributes["adminSt"] = commHttps.AdminSt.ValueString() } - if !commHttps.Annotation.IsUnknown() { + if !commHttps.Annotation.IsNull() && !commHttps.Annotation.IsUnknown() { childMap.Attributes["annotation"] = commHttps.Annotation.ValueString() } else { childMap.Attributes["annotation"] = globalAnnotation } - if !commHttps.CliOnlyMode.IsUnknown() { + if !commHttps.CliOnlyMode.IsNull() && !commHttps.CliOnlyMode.IsUnknown() { childMap.Attributes["cliOnlyMode"] = commHttps.CliOnlyMode.ValueString() } - if !commHttps.ClientCertAuthState.IsUnknown() { + if !commHttps.ClientCertAuthState.IsNull() && !commHttps.ClientCertAuthState.IsUnknown() { childMap.Attributes["clientCertAuthState"] = commHttps.ClientCertAuthState.ValueString() } - if !commHttps.Descr.IsUnknown() { + if !commHttps.Descr.IsNull() && !commHttps.Descr.IsUnknown() { childMap.Attributes["descr"] = commHttps.Descr.ValueString() } - if !commHttps.DhParam.IsUnknown() { + if !commHttps.DhParam.IsNull() && !commHttps.DhParam.IsUnknown() { childMap.Attributes["dhParam"] = commHttps.DhParam.ValueString() } - if !commHttps.GlobalThrottleRate.IsUnknown() { + if !commHttps.GlobalThrottleRate.IsNull() && !commHttps.GlobalThrottleRate.IsUnknown() { childMap.Attributes["globalThrottleRate"] = commHttps.GlobalThrottleRate.ValueString() } - if !commHttps.GlobalThrottleSt.IsUnknown() { + if !commHttps.GlobalThrottleSt.IsNull() && !commHttps.GlobalThrottleSt.IsUnknown() { childMap.Attributes["globalThrottleSt"] = commHttps.GlobalThrottleSt.ValueString() } - if !commHttps.GlobalThrottleUnit.IsUnknown() { + if !commHttps.GlobalThrottleUnit.IsNull() && !commHttps.GlobalThrottleUnit.IsUnknown() { childMap.Attributes["globalThrottleUnit"] = commHttps.GlobalThrottleUnit.ValueString() } - if !commHttps.MaxRequestStatusCount.IsUnknown() { + if !commHttps.MaxRequestStatusCount.IsNull() && !commHttps.MaxRequestStatusCount.IsUnknown() { childMap.Attributes["maxRequestStatusCount"] = commHttps.MaxRequestStatusCount.ValueString() } - if !commHttps.Name.IsUnknown() { + if !commHttps.Name.IsNull() && !commHttps.Name.IsUnknown() { childMap.Attributes["name"] = commHttps.Name.ValueString() } - if !commHttps.NameAlias.IsUnknown() { + if !commHttps.NameAlias.IsNull() && !commHttps.NameAlias.IsUnknown() { childMap.Attributes["nameAlias"] = commHttps.NameAlias.ValueString() } - if !commHttps.NodeExporter.IsUnknown() { + if !commHttps.NodeExporter.IsNull() && !commHttps.NodeExporter.IsUnknown() { childMap.Attributes["nodeExporter"] = commHttps.NodeExporter.ValueString() } - if !commHttps.Port.IsUnknown() { + if !commHttps.Port.IsNull() && !commHttps.Port.IsUnknown() { childMap.Attributes["port"] = commHttps.Port.ValueString() } - if !commHttps.Referer.IsUnknown() { + if !commHttps.Referer.IsNull() && !commHttps.Referer.IsUnknown() { childMap.Attributes["referer"] = commHttps.Referer.ValueString() } - if !commHttps.ServerHeader.IsUnknown() { + if !commHttps.ServerHeader.IsNull() && !commHttps.ServerHeader.IsUnknown() { childMap.Attributes["serverHeader"] = commHttps.ServerHeader.ValueString() } - if !commHttps.SslProtocols.IsUnknown() { + if !commHttps.SslProtocols.IsNull() && !commHttps.SslProtocols.IsUnknown() { var tmpSslProtocols []string commHttps.SslProtocols.ElementsAs(ctx, &tmpSslProtocols, false) childMap.Attributes["sslProtocols"] = strings.Join(tmpSslProtocols, ",") } - if !commHttps.ThrottleRate.IsUnknown() { + if !commHttps.ThrottleRate.IsNull() && !commHttps.ThrottleRate.IsUnknown() { childMap.Attributes["throttleRate"] = commHttps.ThrottleRate.ValueString() } - if !commHttps.ThrottleSt.IsUnknown() { + if !commHttps.ThrottleSt.IsNull() && !commHttps.ThrottleSt.IsUnknown() { childMap.Attributes["throttleSt"] = commHttps.ThrottleSt.ValueString() } - if !commHttps.VisoreAccess.IsUnknown() { + if !commHttps.VisoreAccess.IsNull() && !commHttps.VisoreAccess.IsUnknown() { childMap.Attributes["visoreAccess"] = commHttps.VisoreAccess.ValueString() } - var commRsClientCertCAPlan []CommRsClientCertCACommHttpsResourceModel + var commRsClientCertCAPlan, commRsClientCertCAState []CommRsClientCertCACommHttpsResourceModel commHttps.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCAPlan, false) - for _, commHttpscommRsClientCertCA := range commHttpsState { - if len(commRsClientCertCAPlan) == 0 && len(commHttpscommRsClientCertCA.CommRsClientCertCA.Elements()) == 1 { - commRsClientCertCAChildMap := newAciObjectType() + for _, commHttpscommRsClientCertCAState := range commHttpsState { + commHttpscommRsClientCertCAState.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCAState, false) + if len(commRsClientCertCAPlan) == 0 && len(commRsClientCertCAState) == 1 { + commRsClientCertCAChildMap := NewAciObject() commRsClientCertCAChildMap.Attributes["status"] = "deleted" CommHttpsChildren = append(CommHttpsChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCAChildMap}) } } - if !commHttps.CommRsClientCertCA.IsUnknown() { + if !commHttps.CommRsClientCertCA.IsNull() && !commHttps.CommRsClientCertCA.IsUnknown() { for _, commRsClientCertCA := range commRsClientCertCAPlan { - if !commRsClientCertCA.Annotation.IsUnknown() { + if !commRsClientCertCA.Annotation.IsNull() && !commRsClientCertCA.Annotation.IsUnknown() { commRsClientCertCAChildMap.Attributes["annotation"] = commRsClientCertCA.Annotation.ValueString() } else { commRsClientCertCAChildMap.Attributes["annotation"] = globalAnnotation } - if !commRsClientCertCA.TDn.IsUnknown() { + if !commRsClientCertCA.TDn.IsNull() && !commRsClientCertCA.TDn.IsUnknown() { commRsClientCertCAChildMap.Attributes["tDn"] = commRsClientCertCA.TDn.ValueString() } CommHttpsChildren = append(CommHttpsChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCAChildMap}) } } - var commRsKeyRingPlan []CommRsKeyRingCommHttpsResourceModel + var commRsKeyRingPlan, commRsKeyRingState []CommRsKeyRingCommHttpsResourceModel commHttps.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingPlan, false) - for _, commHttpscommRsKeyRing := range commHttpsState { - if len(commRsKeyRingPlan) == 0 && len(commHttpscommRsKeyRing.CommRsKeyRing.Elements()) == 1 { + for _, commHttpscommRsKeyRingState := range commHttpsState { + commHttpscommRsKeyRingState.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingState, false) + if len(commRsKeyRingPlan) == 0 && len(commRsKeyRingState) == 1 { diags.AddError( "CommRsKeyRing object cannot be deleted", "deletion of child is only possible upon deletion of the parent", @@ -1192,14 +1184,14 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti return nil } } - if !commHttps.CommRsKeyRing.IsUnknown() { + if !commHttps.CommRsKeyRing.IsNull() && !commHttps.CommRsKeyRing.IsUnknown() { for _, commRsKeyRing := range commRsKeyRingPlan { - if !commRsKeyRing.Annotation.IsUnknown() { + if !commRsKeyRing.Annotation.IsNull() && !commRsKeyRing.Annotation.IsUnknown() { commRsKeyRingChildMap.Attributes["annotation"] = commRsKeyRing.Annotation.ValueString() } else { commRsKeyRingChildMap.Attributes["annotation"] = globalAnnotation } - if !commRsKeyRing.TnPkiKeyRingName.IsUnknown() { + if !commRsKeyRing.TnPkiKeyRingName.IsNull() && !commRsKeyRing.TnPkiKeyRingName.IsUnknown() { commRsKeyRingChildMap.Attributes["tnPkiKeyRingName"] = commRsKeyRing.TnPkiKeyRingName.ValueString() } CommHttpsChildren = append(CommHttpsChildren, map[string]interface{}{"commRsKeyRing": commRsKeyRingChildMap}) @@ -1223,15 +1215,15 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti } func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationCommPolResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsUnknown() { + if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { + if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) @@ -1248,7 +1240,7 @@ func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagn } } if delete { - tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete := NewAciObject() tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) @@ -1262,15 +1254,15 @@ func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagn } func getCommPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, tagTagPlan, tagTagState []TagTagCommPolResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsUnknown() { + if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { childMap.Attributes["key"] = tagTag.Key.ValueString() } - if !tagTag.Value.IsUnknown() { + if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) @@ -1287,7 +1279,7 @@ func getCommPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, } } if delete { - tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete := NewAciObject() tagTagChildMapForDelete.Attributes["status"] = "deleted" tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) diff --git a/internal/provider/resource_aci_endpoint_tag_ip.go b/internal/provider/resource_aci_endpoint_tag_ip.go index f01e3cdfd..95b907ed7 100644 --- a/internal/provider/resource_aci_endpoint_tag_ip.go +++ b/internal/provider/resource_aci_endpoint_tag_ip.go @@ -66,6 +66,7 @@ func TagAnnotationFvEpIpTagResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagAnnotationFvEpIpTagResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvEpIpTagResourceModelAttributeTypes()) } @@ -82,6 +83,7 @@ func TagTagFvEpIpTagResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagTagFvEpIpTagResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvEpIpTagResourceModelAttributeTypes()) } @@ -540,15 +542,15 @@ func setFvEpIpTagId(ctx context.Context, data *FvEpIpTagResourceModel) { } func getFvEpIpTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpIpTagResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsUnknown() { + if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { + if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) @@ -565,7 +567,7 @@ func getFvEpIpTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete := NewAciObject() tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) @@ -579,15 +581,15 @@ func getFvEpIpTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } func getFvEpIpTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagTagPlan, tagTagState []TagTagFvEpIpTagResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsUnknown() { + if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { childMap.Attributes["key"] = tagTag.Key.ValueString() } - if !tagTag.Value.IsUnknown() { + if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) @@ -604,7 +606,7 @@ func getFvEpIpTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostic } } if delete { - tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete := NewAciObject() tagTagChildMapForDelete.Attributes["status"] = "deleted" tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) diff --git a/internal/provider/resource_aci_endpoint_tag_mac.go b/internal/provider/resource_aci_endpoint_tag_mac.go index d234cc331..fa03827e6 100644 --- a/internal/provider/resource_aci_endpoint_tag_mac.go +++ b/internal/provider/resource_aci_endpoint_tag_mac.go @@ -66,6 +66,7 @@ func TagAnnotationFvEpMacTagResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagAnnotationFvEpMacTagResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvEpMacTagResourceModelAttributeTypes()) } @@ -82,6 +83,7 @@ func TagTagFvEpMacTagResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagTagFvEpMacTagResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvEpMacTagResourceModelAttributeTypes()) } @@ -540,15 +542,15 @@ func setFvEpMacTagId(ctx context.Context, data *FvEpMacTagResourceModel) { } func getFvEpMacTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpMacTagResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsUnknown() { + if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { + if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) @@ -565,7 +567,7 @@ func getFvEpMacTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di } } if delete { - tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete := NewAciObject() tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) @@ -579,15 +581,15 @@ func getFvEpMacTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di } func getFvEpMacTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagTagPlan, tagTagState []TagTagFvEpMacTagResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsUnknown() { + if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { childMap.Attributes["key"] = tagTag.Key.ValueString() } - if !tagTag.Value.IsUnknown() { + if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) @@ -604,7 +606,7 @@ func getFvEpMacTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnosti } } if delete { - tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete := NewAciObject() tagTagChildMapForDelete.Attributes["status"] = "deleted" tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) 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 107c81d25..742634ae7 100644 --- a/internal/provider/resource_aci_external_management_network_instance_profile.go +++ b/internal/provider/resource_aci_external_management_network_instance_profile.go @@ -69,6 +69,7 @@ func MgmtRsOoBConsMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { "out_of_band_contract_name": types.StringType, } } + func MgmtRsOoBConsMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, MgmtRsOoBConsMgmtInstPResourceModelAttributeTypes()) } @@ -85,6 +86,7 @@ func TagAnnotationMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagAnnotationMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtInstPResourceModelAttributeTypes()) } @@ -101,6 +103,7 @@ func TagTagMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagTagMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtInstPResourceModelAttributeTypes()) } @@ -585,20 +588,20 @@ func setMgmtInstPId(ctx context.Context, data *MgmtInstPResourceModel) { } func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, mgmtRsOoBConsPlan, mgmtRsOoBConsState []MgmtRsOoBConsMgmtInstPResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.MgmtRsOoBCons.IsUnknown() { + if !data.MgmtRsOoBCons.IsNull() && !data.MgmtRsOoBCons.IsUnknown() { mgmtRsOoBConsIdentifiers := []MgmtRsOoBConsIdentifier{} for _, mgmtRsOoBCons := range mgmtRsOoBConsPlan { - if !mgmtRsOoBCons.Annotation.IsUnknown() { + if !mgmtRsOoBCons.Annotation.IsNull() && !mgmtRsOoBCons.Annotation.IsUnknown() { childMap.Attributes["annotation"] = mgmtRsOoBCons.Annotation.ValueString() } else { childMap.Attributes["annotation"] = globalAnnotation } - if !mgmtRsOoBCons.Prio.IsUnknown() { + if !mgmtRsOoBCons.Prio.IsNull() && !mgmtRsOoBCons.Prio.IsUnknown() { childMap.Attributes["prio"] = mgmtRsOoBCons.Prio.ValueString() } - if !mgmtRsOoBCons.TnVzOOBBrCPName.IsUnknown() { + if !mgmtRsOoBCons.TnVzOOBBrCPName.IsNull() && !mgmtRsOoBCons.TnVzOOBBrCPName.IsUnknown() { childMap.Attributes["tnVzOOBBrCPName"] = mgmtRsOoBCons.TnVzOOBBrCPName.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"mgmtRsOoBCons": childMap}) @@ -615,7 +618,7 @@ func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - mgmtRsOoBConsChildMapForDelete := newAciObjectType() + mgmtRsOoBConsChildMapForDelete := NewAciObject() mgmtRsOoBConsChildMapForDelete.Attributes["status"] = "deleted" mgmtRsOoBConsChildMapForDelete.Attributes["tnVzOOBBrCPName"] = mgmtRsOoBCons.TnVzOOBBrCPName.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"mgmtRsOoBCons": mgmtRsOoBConsChildMapForDelete}) @@ -629,15 +632,15 @@ func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Dia } func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtInstPResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsUnknown() { + if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { + if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) @@ -654,7 +657,7 @@ func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete := NewAciObject() tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) @@ -668,15 +671,15 @@ func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } func getMgmtInstPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagTagPlan, tagTagState []TagTagMgmtInstPResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsUnknown() { + if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { childMap.Attributes["key"] = tagTag.Key.ValueString() } - if !tagTag.Value.IsUnknown() { + if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) @@ -693,7 +696,7 @@ func getMgmtInstPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostic } } if delete { - tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete := NewAciObject() tagTagChildMapForDelete.Attributes["status"] = "deleted" tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) diff --git a/internal/provider/resource_aci_external_management_network_subnet.go b/internal/provider/resource_aci_external_management_network_subnet.go index 503bd5322..b37d30cb0 100644 --- a/internal/provider/resource_aci_external_management_network_subnet.go +++ b/internal/provider/resource_aci_external_management_network_subnet.go @@ -65,6 +65,7 @@ func TagAnnotationMgmtSubnetResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagAnnotationMgmtSubnetResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtSubnetResourceModelAttributeTypes()) } @@ -81,6 +82,7 @@ func TagTagMgmtSubnetResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagTagMgmtSubnetResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtSubnetResourceModelAttributeTypes()) } @@ -521,15 +523,15 @@ func setMgmtSubnetId(ctx context.Context, data *MgmtSubnetResourceModel) { } func getMgmtSubnetTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtSubnetResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsUnknown() { + if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { + if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) @@ -546,7 +548,7 @@ func getMgmtSubnetTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di } } if delete { - tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete := NewAciObject() tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) @@ -560,15 +562,15 @@ func getMgmtSubnetTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di } func getMgmtSubnetTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagTagPlan, tagTagState []TagTagMgmtSubnetResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsUnknown() { + if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { childMap.Attributes["key"] = tagTag.Key.ValueString() } - if !tagTag.Value.IsUnknown() { + if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) @@ -585,7 +587,7 @@ func getMgmtSubnetTagTagChildPayloads(ctx context.Context, diags *diag.Diagnosti } } if delete { - tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete := NewAciObject() tagTagChildMapForDelete.Attributes["status"] = "deleted" tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) diff --git a/internal/provider/resource_aci_l3out_consumer_label.go b/internal/provider/resource_aci_l3out_consumer_label.go index 6a2188e02..ed2fe3477 100644 --- a/internal/provider/resource_aci_l3out_consumer_label.go +++ b/internal/provider/resource_aci_l3out_consumer_label.go @@ -70,6 +70,7 @@ func TagAnnotationL3extConsLblResourceModelAttributeTypes() map[string]attr.Type "value": types.StringType, } } + func TagAnnotationL3extConsLblResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationL3extConsLblResourceModelAttributeTypes()) } @@ -86,6 +87,7 @@ func TagTagL3extConsLblResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagTagL3extConsLblResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagL3extConsLblResourceModelAttributeTypes()) } @@ -577,15 +579,15 @@ func setL3extConsLblId(ctx context.Context, data *L3extConsLblResourceModel) { } func getL3extConsLblTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extConsLblResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsUnknown() { + if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { + if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) @@ -602,7 +604,7 @@ func getL3extConsLblTagAnnotationChildPayloads(ctx context.Context, diags *diag. } } if delete { - tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete := NewAciObject() tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) @@ -616,15 +618,15 @@ func getL3extConsLblTagAnnotationChildPayloads(ctx context.Context, diags *diag. } func getL3extConsLblTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagTagPlan, tagTagState []TagTagL3extConsLblResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsUnknown() { + if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { childMap.Attributes["key"] = tagTag.Key.ValueString() } - if !tagTag.Value.IsUnknown() { + if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) @@ -641,7 +643,7 @@ func getL3extConsLblTagTagChildPayloads(ctx context.Context, diags *diag.Diagnos } } if delete { - tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete := NewAciObject() tagTagChildMapForDelete.Attributes["status"] = "deleted" tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) diff --git a/internal/provider/resource_aci_l3out_redistribute_policy.go b/internal/provider/resource_aci_l3out_redistribute_policy.go index 136de9095..8a229a697 100644 --- a/internal/provider/resource_aci_l3out_redistribute_policy.go +++ b/internal/provider/resource_aci_l3out_redistribute_policy.go @@ -65,6 +65,7 @@ func TagAnnotationL3extRsRedistributePolResourceModelAttributeTypes() map[string "value": types.StringType, } } + func TagAnnotationL3extRsRedistributePolResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationL3extRsRedistributePolResourceModelAttributeTypes()) } @@ -81,6 +82,7 @@ func TagTagL3extRsRedistributePolResourceModelAttributeTypes() map[string]attr.T "value": types.StringType, } } + func TagTagL3extRsRedistributePolResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagL3extRsRedistributePolResourceModelAttributeTypes()) } @@ -495,15 +497,15 @@ func setL3extRsRedistributePolId(ctx context.Context, data *L3extRsRedistributeP } func getL3extRsRedistributePolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsRedistributePolResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsUnknown() { + if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { + if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) @@ -520,7 +522,7 @@ func getL3extRsRedistributePolTagAnnotationChildPayloads(ctx context.Context, di } } if delete { - tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete := NewAciObject() tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) @@ -534,15 +536,15 @@ func getL3extRsRedistributePolTagAnnotationChildPayloads(ctx context.Context, di } func getL3extRsRedistributePolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagTagPlan, tagTagState []TagTagL3extRsRedistributePolResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsUnknown() { + if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { childMap.Attributes["key"] = tagTag.Key.ValueString() } - if !tagTag.Value.IsUnknown() { + if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) @@ -559,7 +561,7 @@ func getL3extRsRedistributePolTagTagChildPayloads(ctx context.Context, diags *di } } if delete { - tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete := NewAciObject() tagTagChildMapForDelete.Attributes["status"] = "deleted" tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) diff --git a/internal/provider/resource_aci_out_of_band_contract.go b/internal/provider/resource_aci_out_of_band_contract.go index 288c8da4c..6b786dfa7 100644 --- a/internal/provider/resource_aci_out_of_band_contract.go +++ b/internal/provider/resource_aci_out_of_band_contract.go @@ -71,6 +71,7 @@ func TagAnnotationVzOOBBrCPResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagAnnotationVzOOBBrCPResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationVzOOBBrCPResourceModelAttributeTypes()) } @@ -87,6 +88,7 @@ func TagTagVzOOBBrCPResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagTagVzOOBBrCPResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagVzOOBBrCPResourceModelAttributeTypes()) } @@ -589,15 +591,15 @@ func setVzOOBBrCPId(ctx context.Context, data *VzOOBBrCPResourceModel) { } func getVzOOBBrCPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationVzOOBBrCPResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsUnknown() { + if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { + if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) @@ -614,7 +616,7 @@ func getVzOOBBrCPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete := NewAciObject() tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) @@ -628,15 +630,15 @@ func getVzOOBBrCPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia } func getVzOOBBrCPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagTagPlan, tagTagState []TagTagVzOOBBrCPResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsUnknown() { + if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { childMap.Attributes["key"] = tagTag.Key.ValueString() } - if !tagTag.Value.IsUnknown() { + if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) @@ -653,7 +655,7 @@ func getVzOOBBrCPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostic } } if delete { - tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete := NewAciObject() tagTagChildMapForDelete.Attributes["status"] = "deleted" tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) diff --git a/internal/provider/resource_aci_pim_route_map_entry.go b/internal/provider/resource_aci_pim_route_map_entry.go index c8fadb70c..bbe6c25f2 100644 --- a/internal/provider/resource_aci_pim_route_map_entry.go +++ b/internal/provider/resource_aci_pim_route_map_entry.go @@ -71,6 +71,7 @@ func TagAnnotationPimRouteMapEntryResourceModelAttributeTypes() map[string]attr. "value": types.StringType, } } + func TagAnnotationPimRouteMapEntryResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationPimRouteMapEntryResourceModelAttributeTypes()) } @@ -87,6 +88,7 @@ func TagTagPimRouteMapEntryResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagTagPimRouteMapEntryResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagPimRouteMapEntryResourceModelAttributeTypes()) } @@ -590,15 +592,15 @@ func setPimRouteMapEntryId(ctx context.Context, data *PimRouteMapEntryResourceMo } func getPimRouteMapEntryTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapEntryResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsUnknown() { + if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { + if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) @@ -615,7 +617,7 @@ func getPimRouteMapEntryTagAnnotationChildPayloads(ctx context.Context, diags *d } } if delete { - tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete := NewAciObject() tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) @@ -629,15 +631,15 @@ func getPimRouteMapEntryTagAnnotationChildPayloads(ctx context.Context, diags *d } func getPimRouteMapEntryTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagTagPlan, tagTagState []TagTagPimRouteMapEntryResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsUnknown() { + if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { childMap.Attributes["key"] = tagTag.Key.ValueString() } - if !tagTag.Value.IsUnknown() { + if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) @@ -654,7 +656,7 @@ func getPimRouteMapEntryTagTagChildPayloads(ctx context.Context, diags *diag.Dia } } if delete { - tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete := NewAciObject() tagTagChildMapForDelete.Attributes["status"] = "deleted" tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) diff --git a/internal/provider/resource_aci_pim_route_map_policy.go b/internal/provider/resource_aci_pim_route_map_policy.go index 8818bda4f..47fd6bf0c 100644 --- a/internal/provider/resource_aci_pim_route_map_policy.go +++ b/internal/provider/resource_aci_pim_route_map_policy.go @@ -66,6 +66,7 @@ func TagAnnotationPimRouteMapPolResourceModelAttributeTypes() map[string]attr.Ty "value": types.StringType, } } + func TagAnnotationPimRouteMapPolResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationPimRouteMapPolResourceModelAttributeTypes()) } @@ -82,6 +83,7 @@ func TagTagPimRouteMapPolResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagTagPimRouteMapPolResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagPimRouteMapPolResourceModelAttributeTypes()) } @@ -537,15 +539,15 @@ func setPimRouteMapPolId(ctx context.Context, data *PimRouteMapPolResourceModel) } func getPimRouteMapPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapPolResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsUnknown() { + if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { + if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) @@ -562,7 +564,7 @@ func getPimRouteMapPolTagAnnotationChildPayloads(ctx context.Context, diags *dia } } if delete { - tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete := NewAciObject() tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) @@ -576,15 +578,15 @@ func getPimRouteMapPolTagAnnotationChildPayloads(ctx context.Context, diags *dia } func getPimRouteMapPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagTagPlan, tagTagState []TagTagPimRouteMapPolResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsUnknown() { + if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { childMap.Attributes["key"] = tagTag.Key.ValueString() } - if !tagTag.Value.IsUnknown() { + if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) @@ -601,7 +603,7 @@ func getPimRouteMapPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagn } } if delete { - tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete := NewAciObject() tagTagChildMapForDelete.Attributes["status"] = "deleted" tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) diff --git a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go index 9c94ffa9a..a5477a636 100644 --- a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go +++ b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go @@ -65,6 +65,7 @@ func TagAnnotationMgmtRsOoBConsResourceModelAttributeTypes() map[string]attr.Typ "value": types.StringType, } } + func TagAnnotationMgmtRsOoBConsResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtRsOoBConsResourceModelAttributeTypes()) } @@ -81,6 +82,7 @@ func TagTagMgmtRsOoBConsResourceModelAttributeTypes() map[string]attr.Type { "value": types.StringType, } } + func TagTagMgmtRsOoBConsResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtRsOoBConsResourceModelAttributeTypes()) } @@ -494,15 +496,15 @@ func setMgmtRsOoBConsId(ctx context.Context, data *MgmtRsOoBConsResourceModel) { } func getMgmtRsOoBConsTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtRsOoBConsResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsUnknown() { + if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { childMap.Attributes["key"] = tagAnnotation.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { + if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { childMap.Attributes["value"] = tagAnnotation.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) @@ -519,7 +521,7 @@ func getMgmtRsOoBConsTagAnnotationChildPayloads(ctx context.Context, diags *diag } } if delete { - tagAnnotationChildMapForDelete := newAciObjectType() + tagAnnotationChildMapForDelete := NewAciObject() tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) @@ -533,15 +535,15 @@ func getMgmtRsOoBConsTagAnnotationChildPayloads(ctx context.Context, diags *diag } func getMgmtRsOoBConsTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagTagPlan, tagTagState []TagTagMgmtRsOoBConsResourceModel) []map[string]interface{} { - childMap := newAciObjectType() + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsUnknown() { + if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { childMap.Attributes["key"] = tagTag.Key.ValueString() } - if !tagTag.Value.IsUnknown() { + if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { childMap.Attributes["value"] = tagTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) @@ -558,7 +560,7 @@ func getMgmtRsOoBConsTagTagChildPayloads(ctx context.Context, diags *diag.Diagno } } if delete { - tagTagChildMapForDelete := newAciObjectType() + tagTagChildMapForDelete := NewAciObject() tagTagChildMapForDelete.Attributes["status"] = "deleted" tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) diff --git a/internal/provider/utils.go b/internal/provider/utils.go index 41e99603a..6e2032bb0 100644 --- a/internal/provider/utils.go +++ b/internal/provider/utils.go @@ -15,13 +15,13 @@ import ( "github.com/hashicorp/terraform-plugin-log/tflog" ) -type aciObjectType struct { +type AciObjectType struct { Attributes map[string]interface{} `json:"attributes"` Children []map[string]interface{} `json:"children"` } -func newAciObjectType() aciObjectType { - return aciObjectType{ +func NewAciObject() AciObjectType { + return AciObjectType{ Attributes: make(map[string]interface{}), Children: []map[string]interface{}{}, } From 43f96ad225acc9fc6a0f13ffb70fdd811ef8302d Mon Sep 17 00:00:00 2001 From: Shreyas Date: Tue, 30 Apr 2024 13:56:42 -0700 Subject: [PATCH 08/20] [ignore] Changed full identifier to parent hierarchy --- docs/data-sources/annotation.md | 6 + docs/data-sources/communication_policy.md | 6 +- docs/data-sources/tag.md | 6 + docs/resources/annotation.md | 6 + docs/resources/communication_policy.md | 12 +- docs/resources/tag.md | 6 + .../resource-all-attributes.tf | 4 +- gen/generator.go | 27 +- gen/templates/resource.go.tmpl | 157 ++-- gen/testvars/commPol.yaml | 8 +- .../resource_aci_communication_policy.go | 788 +++++++++++++++--- .../resource_aci_communication_policy_test.go | 32 +- .../provider/resource_aci_endpoint_tag_ip.go | 32 +- .../provider/resource_aci_endpoint_tag_mac.go | 32 +- ...nal_management_network_instance_profile.go | 233 +++++- ..._aci_external_management_network_subnet.go | 32 +- .../resource_aci_l3out_consumer_label.go | 32 +- .../resource_aci_l3out_redistribute_policy.go | 32 +- .../resource_aci_out_of_band_contract.go | 32 +- .../resource_aci_pim_route_map_entry.go | 32 +- .../resource_aci_pim_route_map_policy.go | 32 +- ...lation_to_consumed_out_of_band_contract.go | 32 +- ...ce_aci_relation_to_fallback_route_group.go | 100 ++- .../resource_aci_vrf_fallback_route_group.go | 361 ++++++-- ...rce_aci_vrf_fallback_route_group_member.go | 112 ++- 25 files changed, 1611 insertions(+), 541 deletions(-) diff --git a/docs/data-sources/annotation.md b/docs/data-sources/annotation.md index 8a28ab9f1..de979e7a3 100644 --- a/docs/data-sources/annotation.md +++ b/docs/data-sources/annotation.md @@ -72,8 +72,14 @@ data "aci_annotation" "example_application_epg" { - [aci_external_management_network_instance_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_instance_profile) ([mgmtInstP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtInstP/overview)) - [aci_relation_to_consumed_out_of_band_contract](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/relation_to_consumed_out_of_band_contract) ([mgmtRsOoBCons](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtRsOoBCons/overview)) - [aci_external_management_network_subnet](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_subnet) ([mgmtSubnet](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtSubnet/overview)) +<<<<<<< HEAD - [aci_l3out_node_sid_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/l3out_node_sid_profile) ([mplsNodeSidP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mplsNodeSidP/overview)) - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) +======= + - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) ([pimRouteMapEntry](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapEntry/overview)) + - [aci_pim_route_map_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_policy) ([pimRouteMapPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapPol/overview)) + - Too many classes to display, see model documentation for all possible classes of [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview). +>>>>>>> 1210cc50 ([ignore] Changed full identifier to parent hierarchy) * `key` (key) - (string) The key used to uniquely identify this configuration object. ### Read-Only ### diff --git a/docs/data-sources/communication_policy.md b/docs/data-sources/communication_policy.md index fff9a7072..819436263 100644 --- a/docs/data-sources/communication_policy.md +++ b/docs/data-sources/communication_policy.md @@ -52,7 +52,7 @@ data "aci_communication_policy" "example" { * `owner_tag` (ownerTag) - (string) A tag for enabling clients to add their own data. For example, to indicate who created this object. * `strict_security_on_apic_oob_subnet` (strictSecurityOnApicOOBSubnet) - (string) remove implicit access on apic oob from any apic OOB subnet IP. -* `http_ssl_configuration` - (list) A list of Http Ssl Configuration objects ([commHttps](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commHttps/overview)). +* `http_ssl_configuration` - (list) A list of Http Ssl Configuration (ACI object [commHttps](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commHttps/overview)). * `access_control_allow_credential` (accessControlAllowCredential) - (string) accessControlAllowCredential. * `access_control_allow_origins` (accessControlAllowOrigins) - (string) * `admin_st` (adminSt) - (string) The state of HTTPS communication service. This can be enabled or disabled. @@ -76,10 +76,10 @@ data "aci_communication_policy" "example" { * `throttle_st` (throttleSt) - (string) Login/refresh throttle state. * `visore_access` (visoreAccess) - (string) Visore Access. -* `annotations` - (list) A list of Annotations objects ([tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. -* `tags` - (list) A list of Tags objects ([tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/tag.md b/docs/data-sources/tag.md index 55e36e99e..29b076fd7 100644 --- a/docs/data-sources/tag.md +++ b/docs/data-sources/tag.md @@ -72,8 +72,14 @@ data "aci_tag" "example_application_epg" { - [aci_external_management_network_instance_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_instance_profile) ([mgmtInstP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtInstP/overview)) - [aci_relation_to_consumed_out_of_band_contract](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/relation_to_consumed_out_of_band_contract) ([mgmtRsOoBCons](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtRsOoBCons/overview)) - [aci_external_management_network_subnet](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_subnet) ([mgmtSubnet](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtSubnet/overview)) +<<<<<<< HEAD - [aci_l3out_node_sid_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/l3out_node_sid_profile) ([mplsNodeSidP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mplsNodeSidP/overview)) - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) +======= + - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) ([pimRouteMapEntry](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapEntry/overview)) + - [aci_pim_route_map_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_policy) ([pimRouteMapPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapPol/overview)) + - Too many classes to display, see model documentation for all possible classes of [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview). +>>>>>>> 1210cc50 ([ignore] Changed full identifier to parent hierarchy) * `key` (key) - (string) The key used to uniquely identify this configuration object. ### Read-Only ### diff --git a/docs/resources/annotation.md b/docs/resources/annotation.md index 85e946ee4..127e6224d 100644 --- a/docs/resources/annotation.md +++ b/docs/resources/annotation.md @@ -81,8 +81,14 @@ All examples for the Annotation resource can be found in the [examples](https:// - [aci_external_management_network_instance_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_instance_profile) ([mgmtInstP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtInstP/overview)) - [aci_relation_to_consumed_out_of_band_contract](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/relation_to_consumed_out_of_band_contract) ([mgmtRsOoBCons](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtRsOoBCons/overview)) - [aci_external_management_network_subnet](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_subnet) ([mgmtSubnet](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtSubnet/overview)) +<<<<<<< HEAD - [aci_l3out_node_sid_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/l3out_node_sid_profile) ([mplsNodeSidP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mplsNodeSidP/overview)) - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) +======= + - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) ([pimRouteMapEntry](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapEntry/overview)) + - [aci_pim_route_map_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_policy) ([pimRouteMapPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapPol/overview)) + - Too many classes to display, see model documentation for all possible classes of [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview). +>>>>>>> 1210cc50 ([ignore] Changed full identifier to parent hierarchy) * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. diff --git a/docs/resources/communication_policy.md b/docs/resources/communication_policy.md index 57be179b7..ed209d784 100644 --- a/docs/resources/communication_policy.md +++ b/docs/resources/communication_policy.md @@ -81,13 +81,13 @@ resource "aci_communication_policy" "full_example" { ] annotations = [ { - key = "annotations_1" + key = "key_0" value = "value_1" } ] tags = [ { - key = "tags_1" + key = "key_0" value = "value_1" } ] @@ -119,7 +119,7 @@ All examples for the Communication Policy resource can be found in the [examples - Default: `false` - Valid Values: `no`, `yes`. -* `http_ssl_configuration` - (list) A list of Http Ssl Configuration objects ([commHttps](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commHttps/overview)). Http Ssl Configuration can also be configured using a separate [aci_](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/) resource. +* `http_ssl_configuration` - (list) A list of Http Ssl Configuration (ACI object [commHttps](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commHttps/overview)). Http Ssl Configuration can also be configured using a separate [aci_](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/) resource. #### Required #### @@ -177,14 +177,14 @@ All examples for the Communication Policy resource can be found in the [examples - Default: `enabled` - Valid Values: `disabled`, `enabled`. -* `annotations` - (list) A list of Annotations objects ([tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. -* `tags` - (list) A list of Tags objects ([tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. #### Required #### @@ -199,7 +199,7 @@ An existing Communication Policy can be [imported](https://www.terraform.io/docs terraform import aci_communication_policy.example uni/fabric/comm-{name} ``` -Starting in Terraform version 1.5, an existing Communication Policy can be imported +Starting in Terraform version 1.5, an existing Communication Policy can be imported using [import blocks](https://developer.hashicorp.com/terraform/language/import) via the following configuration: ``` diff --git a/docs/resources/tag.md b/docs/resources/tag.md index d879337bc..413d598ca 100644 --- a/docs/resources/tag.md +++ b/docs/resources/tag.md @@ -81,8 +81,14 @@ All examples for the Tag resource can be found in the [examples](https://github. - [aci_external_management_network_instance_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_instance_profile) ([mgmtInstP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtInstP/overview)) - [aci_relation_to_consumed_out_of_band_contract](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/relation_to_consumed_out_of_band_contract) ([mgmtRsOoBCons](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtRsOoBCons/overview)) - [aci_external_management_network_subnet](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_subnet) ([mgmtSubnet](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtSubnet/overview)) +<<<<<<< HEAD - [aci_l3out_node_sid_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/l3out_node_sid_profile) ([mplsNodeSidP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mplsNodeSidP/overview)) - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) +======= + - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) ([pimRouteMapEntry](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapEntry/overview)) + - [aci_pim_route_map_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_policy) ([pimRouteMapPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapPol/overview)) + - Too many classes to display, see model documentation for all possible classes of [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview). +>>>>>>> 1210cc50 ([ignore] Changed full identifier to parent hierarchy) * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. diff --git a/examples/resources/aci_communication_policy/resource-all-attributes.tf b/examples/resources/aci_communication_policy/resource-all-attributes.tf index d8bd2997d..3f8bc491c 100644 --- a/examples/resources/aci_communication_policy/resource-all-attributes.tf +++ b/examples/resources/aci_communication_policy/resource-all-attributes.tf @@ -35,13 +35,13 @@ resource "aci_communication_policy" "full_example" { ] annotations = [ { - key = "annotations_1" + key = "key_0" value = "value_1" } ] tags = [ { - key = "tags_1" + key = "key_0" value = "value_1" } ] diff --git a/gen/generator.go b/gen/generator.go index 0f77992a3..1c706bc3b 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -648,6 +648,7 @@ type Model struct { Versions string ParentName string GrandParentName string + ParentHierarchy string ChildClasses []string ContainedBy []string Contains []string @@ -723,7 +724,7 @@ type Definitions struct { } // Reads the class details from the meta file and sets all details to the Model -func (m *Model) setClassModel(metaPath string, isChildIteration bool, definitions Definitions, parents, pkgNames, mainParentChildren, parentsList []string) { +func (m *Model) setClassModel(metaPath string, isChildIteration bool, definitions Definitions, parents, pkgNames, mainParentChildren, parentHierarchyList []string) { fileContent, err := os.ReadFile(fmt.Sprintf("%s/%s.json", metaPath, m.PkgName)) if err != nil { log.Fatal("Error when opening file: ", err) @@ -766,17 +767,21 @@ func (m *Model) setClassModel(metaPath string, isChildIteration bool, definition - Incorrect: Parent -> Child -> Grandchild // TODO add grandchild logic */ - parentsList = append(parentsList, parents...) - if len(parents) != 0 { - m.SetGrandParentName(parentsList, parents[0]) + m.ParentHierarchy = fmt.Sprintf("%s", strings.Join(reverseList(parentHierarchyList), "")) + + if len(parentHierarchyList) == 0 { + parentHierarchyList = []string{m.ResourceClassName} + } else { + parentHierarchyList = append(parentHierarchyList, m.ResourceClassName) } + if len(m.ChildClasses) > 0 { mainParentChildren := append(mainParentChildren, m.ChildClasses...) m.HasChild = true m.Children = make(map[string]Model) for _, child := range m.ChildClasses { childModel := Model{PkgName: child} - childModel.setClassModel(metaPath, true, definitions, []string{m.ResourceClassName}, pkgNames, mainParentChildren, parentsList) + childModel.setClassModel(metaPath, true, definitions, []string{m.PkgName}, pkgNames, mainParentChildren, parentHierarchyList) m.Children[child] = childModel if childModel.HasValidValues { m.HasValidValues = true @@ -891,7 +896,7 @@ func (m *Model) SetClassChildren(classDetails interface{}, pkgNames, mainParentC // TODO check if this condition is correct since there might be cases where that we should exclude if !strings.HasSuffix(rn, "-") || strings.HasPrefix(rn, "rs") || slices.Contains(alwaysIncludeChildren, className.(string)) { pkgName := strings.ReplaceAll(className.(string), ":", "") - if slices.Contains(pkgNames, pkgName) && !slices.Contains(mainParentChildren, pkgName) { + if slices.Contains(pkgNames, pkgName) { childClasses = append(childClasses, pkgName) } } @@ -963,6 +968,14 @@ func (m *Model) SetGrandParentName(parentList []string, parent string) { } } +func reverseList(items []string) []string { + reversedList := make([]string, len(items)) + for i, item := range items { + reversedList[len(items)-1-i] = item + } + return reversedList +} + // Determine if a class is allowed to be deleted as defined in the classes.yaml file // Flag created to ensure classes that only classes allowed to be deleted are deleted func (m *Model) SetResourceNotesAndWarnigns(classPkgName string, definitions Definitions) { @@ -1541,7 +1554,7 @@ func setDocumentationData(m *Model, definitions Definitions) { if len(resourcesNotFound) != 0 && len(resourcesFound) < docsParentDnAmount { if len(resourcesNotFound) > docsParentDnAmount-len(resourcesFound) { // TODO catch default classes and add to documentation - resourcesNotFound = resourcesNotFound[0:(docsParentDnAmount - len(resourcesFound))] + //resourcesNotFound = resourcesNotFound[0:(docsParentDnAmount - len(resourcesFound))] m.DocumentationParentDns = append(m.DocumentationParentDns, fmt.Sprintf("Too many classes to display, see model documentation for all possible classes of %s.", GetDevnetDocForClass(m.PkgName))) } else { var resourceDetails string diff --git a/gen/templates/resource.go.tmpl b/gen/templates/resource.go.tmpl index 578373653..22b517604 100644 --- a/gen/templates/resource.go.tmpl +++ b/gen/templates/resource.go.tmpl @@ -233,7 +233,7 @@ func (r *{{.ResourceClassName}}Resource) Create(ctx context.Context, req resourc {{ if .HasChild}} {{- range .Children}} - var {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{.ParentName}}ResourceModel + var {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModel data.{{ .ResourceClassName }}.ElementsAs(ctx, &{{.PkgName}}Plan, false) stateData.{{ .ResourceClassName }}.ElementsAs(ctx, &{{.PkgName}}State, false) {{- end}} @@ -503,10 +503,10 @@ func getAndSet{{.ResourceClassName}}Attributes(ctx context.Context, diags *diag. {{- if not $enteredGrandChildGetAndSetAttributesZone }} {{- $enteredGrandChildGetAndSetAttributesZone = true }} } - childrenOf{{.ParentName}}, childrenOf{{.ParentName}}Exist:= childClassDetails.(map[string]interface{})["children"] - if childrenOf{{.ParentName}}Exist { - for _, child{{.ParentName}} := range childrenOf{{.ParentName}}.([]interface{}) { - for childClassName{{.ParentName}}, childClassDetails{{.ParentName}} := range child{{.ParentName}}.(map[string]interface{}) { + childrenOf{{.ParentHierarchy}}, childrenOf{{.ParentHierarchy}}Exist:= childClassDetails.(map[string]interface{})["children"] + if childrenOf{{.ParentHierarchy}}Exist { + for _, child{{.ParentHierarchy}} := range childrenOf{{.ParentHierarchy}}.([]interface{}) { + for childClassName{{.ParentHierarchy}}, childClassDetails{{.ParentHierarchy}} := range child{{.ParentHierarchy}}.(map[string]interface{}) { {{- end}} {{- template "getAndSetGrandChildren" . }} {{- end }} @@ -515,8 +515,8 @@ func getAndSet{{.ResourceClassName}}Attributes(ctx context.Context, diags *diag. } } {{- range .Children}} - {{.ResourceClassName}}Set,_:=types.SetValueFrom(ctx,{{.ResourceClassName}}{{.ParentName}}ResourceModelElementType(),{{.ResourceClassName}}{{.ParentName}}List) - {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}}={{.ResourceClassName}}Set + {{.ResourceClassName}}Set,_:=types.SetValueFrom(ctx,{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModelElementType(),{{.ResourceClassName}}{{.ParentHierarchy}}List) + {{.ParentHierarchy}}.{{.ResourceClassName}}={{.ResourceClassName}}Set {{- end}} {{- else}} } @@ -592,7 +592,8 @@ func set{{.ResourceClassName}}Id(ctx context.Context, data *{{.ResourceClassName {{ range .Children}} -func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *{{$.ResourceClassName}}ResourceModel, {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel) []map[string]interface{} { +{{- $child:= .}} +func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *{{$.ResourceClassName}}ResourceModel, {{.PkgName}}{{.ParentHierarchy}}Plan, {{.PkgName}}{{.ParentHierarchy}}State []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} {{- $enteredGrandChildDeclarationZone := false }} @@ -601,26 +602,26 @@ func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context {{- template "grandChildDeclarationInChildPayloadFunction" . }} {{- end}} {{- range .Children}} - {{- if $enteredGrandChildDeclarationZone }} + {{- if $enteredGrandChildDeclarationZone }} {{- $enteredGrandChildDeclarationZone = false }} - {{.ParentName}}Children := make([]map[string]interface{}, 0) - {{- end}} + {{.ParentHierarchy}}Children := make([]map[string]interface{}, 0) {{- end}} + {{- end}} if !data.{{.ResourceClassName}}.IsNull() && !data.{{.ResourceClassName}}.IsUnknown() { {{- if .IdentifiedBy}} {{ .PkgName }}Identifiers := []{{.ResourceClassName}}Identifier{} {{- end}} - for _, {{ .PkgName }} := range {{ .PkgName }}Plan { + for _, {{ .PkgName }}{{.ParentHierarchy}} := range {{ .PkgName }}{{.ParentHierarchy}}Plan { {{- range .Properties}} - if !{{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsNull() && !{{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsUnknown(){ + if !{{ .PkgName }}{{$child.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsNull() && !{{ .PkgName }}{{$child.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsUnknown(){ {{- if eq .ValueType "bitmask"}} var tmp{{ .Name }} []string - {{ .PkgName }}.{{ .Name }}.ElementsAs(ctx, &tmp{{ .Name }}, false) + {{ .PkgName }}{{$child.ParentHierarchy}}.{{ .Name }}.ElementsAs(ctx, &tmp{{ .Name }}, false) childMap.Attributes["{{ .PropertyName }}"] = strings.Join(tmp{{ .Name }}, ",") {{- else if eq .Name "Id"}} - childMap.Attributes["{{ .PropertyName }}"] = {{ .PkgName }}.{{.ResourceClassName}}{{ .Name }}.ValueString() + childMap.Attributes["{{ .PropertyName }}"] = {{ .PkgName }}{{$child.ParentHierarchy}}.{{.ResourceClassName}}{{ .Name }}.ValueString() {{- else}} - childMap.Attributes["{{ .PropertyName }}"] = {{ .PkgName }}.{{ .Name }}.ValueString() + childMap.Attributes["{{ .PropertyName }}"] = {{ .PkgName }}{{$child.ParentHierarchy}}.{{ .Name }}.ValueString() {{- end}} } {{- if eq .Name "Annotation" }} else { childMap.Attributes["annotation"] = globalAnnotation @@ -634,7 +635,7 @@ func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context {{- range .Children}} {{- if $enteredGrandChildPayloadZone }} {{- $enteredGrandChildPayloadZone = false }} - childMap.Children = {{.ParentName}}Children + childMap.Children = {{.ParentHierarchy}}Children {{- end}} {{- end}} childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": childMap}) @@ -642,14 +643,14 @@ func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context {{ .PkgName }}Identifier := {{ .ResourceClassName }}Identifier{} {{- range .Properties}} {{- if .IsNaming}} - {{ .PkgName }}Identifier.{{.Name}} = {{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}} + {{ .PkgName }}Identifier.{{.Name}} = {{ .PkgName }}{{$child.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}} {{- end}} {{- end}} {{ .PkgName }}Identifiers = append({{ .PkgName }}Identifiers, {{ .PkgName }}Identifier) {{- end}} } {{- if .IdentifiedBy}} - for _, {{ .PkgName }} := range {{ .PkgName }}State { + for _, {{ .PkgName }} := range {{ .PkgName }}{{.ParentHierarchy}}State { delete := true for _, {{ .PkgName }}Identifier := range {{ .PkgName }}Identifiers { {{$i := 1}}{{$length := len .IdentifiedBy}} if @@ -663,22 +664,22 @@ func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context } } if delete { - {{.PkgName}}ChildMapForDelete := NewAciObject() - {{.PkgName}}ChildMapForDelete.Attributes["status"] = "deleted" + {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete := NewAciObject() + {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete.Attributes["status"] = "deleted" {{- range .Properties}} {{- if .IsNaming }} - {{.PkgName}}ChildMapForDelete.Attributes["{{.PropertyName}}"] = {{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.ValueString() + {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete.Attributes["{{.PropertyName}}"] = {{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.ValueString() {{- end}} {{- end}} - childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": {{.PkgName}}ChildMapForDelete}) + childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete}) } } {{- else}} - if len({{ .PkgName }}Plan) == 0 && len({{ .PkgName }}State) == 1 { + if len({{ .PkgName }}{{.ParentHierarchy}}Plan) == 0 && len({{ .PkgName }}{{.ParentHierarchy}}State) == 1 { {{- if .AllowDelete}} - {{.PkgName}}ChildMapForDelete := NewAciObject() - {{.PkgName}}ChildMapForDelete.Attributes["status"] = "deleted" - childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": {{.PkgName}}ChildMapForDelete}) + {{.PkgName}}{{.ParentHierarchy}}ChildMapForDelete := NewAciObject() + {{.PkgName}}{{.ParentHierarchy}}ChildMapForDelete.Attributes["status"] = "deleted" + childPayloads = append(childPayloads, map[string]interface{}{"{{ .PkgName }}": {{.PkgName}}{{.ParentHierarchy}}ChildMapForDelete}) {{- else}} diags.AddError( "{{ .ResourceClassName }} object cannot be deleted", @@ -752,8 +753,8 @@ func get{{.ResourceClassName}}CreateJsonPayload(ctx context.Context, diags *diag {{/* A sub template for the child structs used in the structs definiton section. */}} {{- define "childStructsAndAttributeTypes" }} -// {{.ResourceClassName}}{{.ParentName}}ResourceModel describes the resource data model for the children without relation ships. -type {{.ResourceClassName}}{{.ParentName}}ResourceModel struct { +// {{.ResourceClassName}}{{.ParentHierarchy}}ResourceModel describes the resource data model for the children without relation ships. +type {{.ResourceClassName}}{{.ParentHierarchy}}ResourceModel struct { {{- range .Properties}} {{- if eq .ValueType "bitmask"}} {{ .Name }} types.Set `tfsdk:"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}"` @@ -768,7 +769,7 @@ type {{.ResourceClassName}}{{.ParentName}}ResourceModel struct { {{- end}} } -func {{.ResourceClassName}}{{.ParentName}}ResourceModelAttributeTypes() map[string]attr.Type { +func {{.ResourceClassName}}{{.ParentHierarchy}}ResourceModelAttributeTypes() map[string]attr.Type { return map[string]attr.Type{ {{- range .Properties}} {{- if eq .ValueType "bitmask"}} @@ -785,8 +786,8 @@ func {{.ResourceClassName}}{{.ParentName}}ResourceModelAttributeTypes() map[stri } } -func {{.ResourceClassName}}{{.ParentName}}ResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{},{{.ResourceClassName}}{{.ParentName}}ResourceModelAttributeTypes()) +func {{.ResourceClassName}}{{.ParentHierarchy}}ResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{},{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModelAttributeTypes()) } {{- range .Children}} {{- template "childStructsAndAttributeTypes" . }} @@ -861,15 +862,15 @@ func {{.ResourceClassName}}{{.ParentName}}ResourceModelElementType() attr.TypeWi {{/* A sub template for the grand child attributes used in the Payload function. */}} {{- define "grandChildPayload" }} -var {{.PkgName}}Plan, {{.PkgName}}State []{{.ResourceClassName}}{{.ParentName}}ResourceModel -{{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}Plan, false) -for _, {{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}}State := range {{.ParentName | lowerFirstCharacter}}State { -{{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}}State.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}State, false) -if len({{ .PkgName }}Plan) == 0 && len({{.PkgName}}State) == 1 { +var {{.PkgName}}{{.ParentHierarchy}}Plan, {{.PkgName}}{{.ParentHierarchy}}State []{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModel +{{.ParentHierarchy | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}{{.ParentHierarchy}}Plan, false) +for _, {{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}}State := range {{.ParentHierarchy | lowerFirstCharacter}}State { +{{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}}State.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}{{.ParentHierarchy}}State, false) +if len({{ .PkgName }}{{.ParentHierarchy}}Plan) == 0 && len({{.PkgName}}{{.ParentHierarchy}}State) == 1 { {{- if .AllowDelete}} - {{.PkgName}}ChildMap := NewAciObject() - {{.PkgName}}ChildMap.Attributes["status"] = "deleted" - {{ .ParentName }}Children = append({{ .ParentName }}Children, map[string]interface{}{"{{.PkgName}}": {{.PkgName}}ChildMap}) + {{.PkgName}}{{.ParentHierarchy}}ChildMap := NewAciObject() + {{.PkgName}}{{.ParentHierarchy}}ChildMap.Attributes["status"] = "deleted" + {{ .ParentHierarchy }}Children = append({{ .ParentHierarchy }}Children, map[string]interface{}{"{{.PkgName}}": {{.PkgName}}{{.ParentHierarchy}}ChildMap}) {{- else}} diags.AddError( "{{ .ResourceClassName }} object cannot be deleted", @@ -879,27 +880,27 @@ if len({{ .PkgName }}Plan) == 0 && len({{.PkgName}}State) == 1 { {{- end }} } } -if !{{ .ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.IsNull() && !{{ .ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.IsUnknown(){ -for _, {{ .PkgName }} := range {{.PkgName}}Plan { +if !{{ .ParentHierarchy | lowerFirstCharacter}}.{{.ResourceClassName}}.IsNull() && !{{ .ParentHierarchy | lowerFirstCharacter}}.{{.ResourceClassName}}.IsUnknown(){ +for _, {{ .PkgName }}{{.ParentHierarchy}} := range {{.PkgName}}{{.ParentHierarchy}}Plan { {{- range .Properties}} - if !{{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsNull() && !{{ .PkgName }}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsUnknown(){ + if !{{ .PkgName }}{{$.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsNull() && !{{ .PkgName }}{{$.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsUnknown(){ {{- if eq .ValueType "bitmask"}} var tmp{{ .Name }} []string - {{ .PkgName }}.{{ .Name }}.ElementsAs(ctx, &tmp{{ .Name }}, false) - {{.PkgName}}ChildMap.Attributes["{{ .PropertyName }}"] = strings.Join(tmp{{ .Name }}, ",") + {{ .PkgName }}{{$.ParentHierarchy}}.{{ .Name }}.ElementsAs(ctx, &tmp{{ .Name }}, false) + {{.PkgName}}{{$.ParentHierarchy}}ChildMap.Attributes["{{ .PropertyName }}"] = strings.Join(tmp{{ .Name }}, ",") {{- else if eq .Name "Id"}} - {{.PkgName}}ChildMap.Attributes["{{ .PropertyName }}"] = {{ .PkgName }}.{{.ResourceClassName}}{{ .Name }}.ValueString() + {{.PkgName}}{{$.ParentHierarchy}}ChildMap.Attributes["{{ .PropertyName }}"] = {{ .PkgName }}{{$.ParentHierarchy}}.{{.ResourceClassName}}{{ .Name }}.ValueString() {{- else}} - {{.PkgName}}ChildMap.Attributes["{{ .PropertyName }}"] = {{ .PkgName }}.{{ .Name }}.ValueString() + {{.PkgName}}{{$.ParentHierarchy}}ChildMap.Attributes["{{ .PropertyName }}"] = {{ .PkgName }}{{$.ParentHierarchy}}.{{ .Name }}.ValueString() {{- end}} } {{- if eq .Name "Annotation" }} else { - {{.PkgName}}ChildMap.Attributes["annotation"] = globalAnnotation + {{.PkgName}}{{$.ParentHierarchy}}ChildMap.Attributes["annotation"] = globalAnnotation } {{- end}} {{- end}} {{- range .Children}} {{- template "grandChildPayload" . }} {{- end}} - {{ .ParentName }}Children = append({{ .ParentName }}Children, map[string]interface{}{"{{.PkgName}}": {{.PkgName}}ChildMap}) + {{ .ParentHierarchy }}Children = append({{ .ParentHierarchy }}Children, map[string]interface{}{"{{.PkgName}}": {{.PkgName}}{{$.ParentHierarchy}}ChildMap}) } } {{- end }} @@ -907,11 +908,11 @@ for _, {{ .PkgName }} := range {{.PkgName}}Plan { {{/* A sub template to declare child lists in the get and set attributes function. */}} {{- define "declareChildListsInGetandSetAttributesFunction" }} -{{.ResourceClassName}}{{.ParentName}} := {{ .ResourceClassName}}{{.ParentName}}ResourceModel{} +{{.ResourceClassName}}{{.ParentHierarchy}} := {{ .ResourceClassName}}{{.ParentHierarchy}}ResourceModel{} {{- if .IdentifiedBy}} -{{ .ResourceClassName }}{{$.ParentName}}List := make([]{{.ResourceClassName}}{{$.ParentName}}ResourceModel, 0) +{{ .ResourceClassName }}{{.ParentHierarchy}}List := make([]{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModel, 0) {{- else}} -{{ .ResourceClassName }}{{$.ParentName}}List := make([]{{.ResourceClassName}}{{$.ParentName}}ResourceModel, 0) +{{ .ResourceClassName }}{{.ParentHierarchy}}List := make([]{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModel, 0) {{- end}} {{- range .Children}} {{- template "declareChildListsInGetandSetAttributesFunction" . }} @@ -921,45 +922,45 @@ for _, {{ .PkgName }} := range {{.PkgName}}Plan { {{/* A sub template for the grand child attributes used in the get and set attributes function. */}} {{- define "getAndSetGrandChildren" }} -if childClassName{{.ParentName}} == "{{.PkgName}}"{ -{{.PkgName}}childAttributeValue:= childClassDetails{{.ParentName}}.(map[string]interface{})["attributes"].(map[string]interface{}) +if childClassName{{.ParentHierarchy}} == "{{.PkgName}}"{ +{{.PkgName}}childAttributeValue:= childClassDetails{{.ParentHierarchy}}.(map[string]interface{})["attributes"].(map[string]interface{}) for childAttributeName, childAttributeValue := range {{.PkgName}}childAttributeValue { {{- range .Properties}} {{- if eq .ValueType "bitmask"}} {{- if containsNoneAttributeValue .ValidValues}} if childAttributeName == "{{.PropertyName}}" && childAttributeValue.(string) == "" { - {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, {{.ResourceClassName}}{{$.ParentName}}.{{.Name}}.ElementType(ctx), []string{"none"}) - {{.ResourceClassName}}{{$.ParentName}}.{{.Name}} = {{.PropertyName}}Set + {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, {{.ResourceClassName}}{{$.ParentHierarchy}}.{{.Name}}.ElementType(ctx), []string{"none"}) + {{.ResourceClassName}}{{$.ParentHierarchy}}.{{.Name}} = {{.PropertyName}}Set } else if childAttributeName == "{{.PropertyName}}" { {{.PropertyName}}List := strings.Split(childAttributeValue.(string), ",") - var data{{.ParentName}}{{.GrandParentName}} []{{.ParentName}}{{.GrandParentName}}ResourceModel - data.{{.ParentName}}.ElementsAs(ctx,&data{{.ParentName}}{{.GrandParentName}},false) - for _, {{.ParentName | lowerFirstCharacter}} := range data{{.ResourceClassName}}{{.ParentName}} { - {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, {{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementType(ctx),{{.PropertyName}}List) - {{.ResourceClassName}}{{$.ParentName}}.{{.Name}} = {{.PropertyName}}Set + var data{{.ParentHierarchy}} []{{.ParentHierarchy}}ResourceModel + data.{{.ParentHierarchy}}.ElementsAs(ctx,&data{{.ParentHierarchy}},false) + for _, {{.ParentHierarchy | lowerFirstCharacter}} := range data{{.ResourceClassName}}{{.ParentHierarchy}} { + {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, {{.ParentHierarchy | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementType(ctx),{{.PropertyName}}List) + {{.ResourceClassName}}{{$.ParentHierarchy}}.{{.Name}} = {{.PropertyName}}Set } } {{- else}} if childAttributeName == "{{.PropertyName}}" { {{.PropertyName}}List := strings.Split(childAttributeValue.(string), ",") - var data{{.ParentName}}{{.GrandParentName}} []{{.ParentName}}{{.GrandParentName}}ResourceModel - data.{{.ParentName}}.ElementsAs(ctx,&data{{.ParentName}}{{.GrandParentName}},false) - for _, {{.ParentName | lowerFirstCharacter}} := range data{{.ResourceClassName}}{{.ParentName}} { - {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, {{.ParentName | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementType(ctx),{{.PropertyName}}List) - {{.ResourceClassName}}{{$.ParentName}}.{{.Name}} = {{.PropertyName}}Set + var data{{.ParentHierarchy}} []{{.ParentHierarchy}}ResourceModel + data.{{.ParentHierarchy}}.ElementsAs(ctx,&data{{.ParentHierarchy}},false) + for _, {{.ParentHierarchy | lowerFirstCharacter}} := range data{{.ResourceClassName}}{{.ParentHierarchy}} { + {{.PropertyName}}Set, _ := types.SetValueFrom(ctx, {{.ParentHierarchy | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementType(ctx),{{.PropertyName}}List) + {{.ResourceClassName}}{{$.ParentHierarchy}}.{{.Name}} = {{.PropertyName}}Set } } {{- end}} {{- else}} {{- if containsNoneAttributeValue .ValidValues}} if childAttributeName == "{{.PropertyName}}" && childAttributeValue.(string) == "" { - {{.ResourceClassName}}{{.ParentName}}.{{.Name}} = basetypes.NewStringValue("none") + {{.ResourceClassName}}{{.ParentHierarchy}}.{{.Name}} = basetypes.NewStringValue("none") } else if childAttributeName == "{{.PropertyName}}" { - {{.ResourceClassName}}{{$.ParentName}}.{{.Name}} = basetypes.NewStringValue(childAttributeValue.(string)) + {{.ResourceClassName}}{{$.ParentHierarchy}}.{{.Name}} = basetypes.NewStringValue(childAttributeValue.(string)) } {{- else}} if childAttributeName == "{{.PropertyName}}" { - {{.ResourceClassName}}{{$.ParentName}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}} = basetypes.NewStringValue(childAttributeValue.(string)) + {{.ResourceClassName}}{{$.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}} = basetypes.NewStringValue(childAttributeValue.(string)) } {{- end}} {{- end}} @@ -969,10 +970,10 @@ for childAttributeName, childAttributeValue := range {{.PkgName}}childAttributeV {{- if not $enteredGrandChildGetAndSetAttributesZone }} {{- $enteredGrandChildGetAndSetAttributesZone = true }} } - childrenOf{{.ParentName}}, childrenOf{{.ParentName}}Exist:= childClassDetails.(map[string]interface{})["children"] - if childrenOf{{.ParentName}}Exist { - for _, child{{.ParentName}} := range childrenOf{{.ParentName}}.([]interface{}) { - for childClassName{{.ParentName}}, childClassDetails{{.ParentName}} := range child{{.ParentName}}.(map[string]interface{}) { + childrenOf{{.ParentHierarchy}}, childrenOf{{.ParentHierarchy}}Exist:= childClassDetails{{$.ParentHierarchy}}.(map[string]interface{})["children"] + if childrenOf{{.ParentHierarchy}}Exist { + for _, child{{.ParentHierarchy}} := range childrenOf{{.ParentHierarchy}}.([]interface{}) { + for childClassName{{.ParentHierarchy}}, childClassDetails{{.ParentHierarchy}} := range child{{.ParentHierarchy}}.(map[string]interface{}) { {{- end}} {{- template "getAndSetGrandChildren" . }} {{- end }} @@ -981,20 +982,20 @@ for childAttributeName, childAttributeValue := range {{.PkgName}}childAttributeV } } {{- range .Children}} - {{.ResourceClassName}}Set,_:=types.SetValueFrom(ctx,{{.ResourceClassName}}{{.ParentName}}ResourceModelElementType(),{{.ResourceClassName}}{{.ParentName}}List) - {{.ParentName}}{{.GrandParentName}}.{{.ResourceClassName}}={{.ResourceClassName}}Set + {{.ResourceClassName}}Set,_:=types.SetValueFrom(ctx,{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModelElementType(),{{.ResourceClassName}}{{.ParentHierarchy}}List) + {{.ParentHierarchy}}.{{.ResourceClassName}}={{.ResourceClassName}}Set {{- end}} {{- else}} } {{- end}} - {{.ResourceClassName}}{{$.ParentName}}List = append({{.ResourceClassName}}{{$.ParentName}}List, {{.ResourceClassName}}{{$.ParentName}}) + {{.ResourceClassName}}{{$.ParentHierarchy}}List = append({{.ResourceClassName}}{{$.ParentHierarchy}}List, {{.ResourceClassName}}{{$.ParentHierarchy}}) } {{- end }} {{/* A sub template for grand child declaration in the child payload function. */}} {{- define "grandChildDeclarationInChildPayloadFunction" }} -{{.PkgName}}ChildMap := NewAciObject() +{{.PkgName}}{{.ParentHierarchy}}ChildMap := NewAciObject() {{- $enteredGrandChildDeclarationZone := false }} {{- range .Children}} {{- $enteredGrandChildDeclarationZone = true }} @@ -1003,7 +1004,7 @@ for childAttributeName, childAttributeValue := range {{.PkgName}}childAttributeV {{- range .Children}} {{- if $enteredGrandChildDeclarationZone }} {{- $enteredGrandChildDeclarationZone = false }} -{{.ParentName}}Children := make([]map[string]interface{}, 0) +{{.ParentHierarchy}}Children := make([]map[string]interface{}, 0) {{- end}} {{- end}} {{- end}} diff --git a/gen/testvars/commPol.yaml b/gen/testvars/commPol.yaml index f9175d055..a495f5a47 100644 --- a/gen/testvars/commPol.yaml +++ b/gen/testvars/commPol.yaml @@ -76,16 +76,16 @@ children: visore_access: "enabled" annotations: - - key: "annotations_1" + - key: "key_0" value: "value_1" - - key: "annotations_2" + - key: "key_1" value: "value_2" tags: - - key: "tags_1" + - key: "key_0" value: "value_1" - - key: "tags_2" + - key: "key_1" value: "value_2" diff --git a/internal/provider/resource_aci_communication_policy.go b/internal/provider/resource_aci_communication_policy.go index 73303ad51..c25c84987 100644 --- a/internal/provider/resource_aci_communication_policy.go +++ b/internal/provider/resource_aci_communication_policy.go @@ -84,6 +84,8 @@ type CommHttpsCommPolResourceModel struct { VisoreAccess types.String `tfsdk:"visore_access"` CommRsClientCertCA types.Set `tfsdk:"tp"` CommRsKeyRing types.Set `tfsdk:"key_ring"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` } func CommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { @@ -112,6 +114,8 @@ func CommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { "visore_access": types.StringType, "tp": types.SetType{ElemType: types.StringType}, "key_ring": types.SetType{ElemType: types.StringType}, + "annotations": types.SetType{ElemType: types.StringType}, + "tags": types.SetType{ElemType: types.StringType}, } } @@ -119,38 +123,148 @@ func CommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommHttpsCommPolResourceModelAttributeTypes()) } -// CommRsClientCertCACommHttpsResourceModel describes the resource data model for the children without relation ships. -type CommRsClientCertCACommHttpsResourceModel struct { - Annotation types.String `tfsdk:"annotation"` - TDn types.String `tfsdk:"target_dn"` +// CommRsClientCertCACommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. +type CommRsClientCertCACommHttpsCommPolResourceModel struct { + Annotation types.String `tfsdk:"annotation"` + TDn types.String `tfsdk:"target_dn"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` } -func CommRsClientCertCACommHttpsResourceModelAttributeTypes() map[string]attr.Type { +func CommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { return map[string]attr.Type{ - "annotation": types.StringType, - "target_dn": types.StringType, + "annotation": types.StringType, + "target_dn": types.StringType, + "annotations": types.SetType{ElemType: types.StringType}, + "tags": types.SetType{ElemType: types.StringType}, } } -func CommRsClientCertCACommHttpsResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommRsClientCertCACommHttpsResourceModelAttributeTypes()) +func CommRsClientCertCACommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes()) } -// CommRsKeyRingCommHttpsResourceModel describes the resource data model for the children without relation ships. -type CommRsKeyRingCommHttpsResourceModel struct { +// TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes()) +} + +// TagTagCommRsClientCertCACommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. +type TagTagCommRsClientCertCACommHttpsCommPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagCommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagCommRsClientCertCACommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagCommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes()) +} + +// CommRsKeyRingCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. +type CommRsKeyRingCommHttpsCommPolResourceModel struct { Annotation types.String `tfsdk:"annotation"` TnPkiKeyRingName types.String `tfsdk:"tn_pki_key_ring_name"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` } -func CommRsKeyRingCommHttpsResourceModelAttributeTypes() map[string]attr.Type { +func CommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { return map[string]attr.Type{ "annotation": types.StringType, "tn_pki_key_ring_name": types.StringType, + "annotations": types.SetType{ElemType: types.StringType}, + "tags": types.SetType{ElemType: types.StringType}, + } +} + +func CommRsKeyRingCommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes()) +} + +// TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, } } -func CommRsKeyRingCommHttpsResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommRsKeyRingCommHttpsResourceModelAttributeTypes()) +func TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes()) +} + +// TagTagCommRsKeyRingCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. +type TagTagCommRsKeyRingCommHttpsCommPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagCommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagCommRsKeyRingCommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagCommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes()) +} + +// TagAnnotationCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationCommHttpsCommPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationCommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationCommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationCommHttpsCommPolResourceModelAttributeTypes()) +} + +// TagTagCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. +type TagTagCommHttpsCommPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagCommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagCommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagCommHttpsCommPolResourceModelAttributeTypes()) } // TagAnnotationCommPolResourceModel describes the resource data model for the children without relation ships. @@ -554,6 +668,62 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest }, MarkdownDescription: `The distinguished name of the target.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, }, }, @@ -587,6 +757,118 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest }, MarkdownDescription: `The HTTP connection key ring. Each PKI device holds a pair of asymmetric Rivest-Shamir-Adleman (RSA) or Elliptic Curve Cryptography (ECC) encryption keys, one kept private and one made public, stored in an internal key ring.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + }, + }, + }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, }, }, }, @@ -828,7 +1110,7 @@ func (r *CommPolResource) ImportState(ctx context.Context, req resource.ImportSt } func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *CommPolResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "commPol,commHttps,tagAnnotation,tagTag,commRsClientCertCA,commRsKeyRing"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "commPol,commHttps,tagAnnotation,tagTag,commRsClientCertCA,commRsKeyRing,tagAnnotation,tagTag,tagAnnotation,tagTag,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -886,10 +1168,22 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl } CommHttpsCommPol := CommHttpsCommPolResourceModel{} CommHttpsCommPolList := make([]CommHttpsCommPolResourceModel, 0) - CommRsClientCertCACommHttps := CommRsClientCertCACommHttpsResourceModel{} - CommRsClientCertCACommHttpsList := make([]CommRsClientCertCACommHttpsResourceModel, 0) - CommRsKeyRingCommHttps := CommRsKeyRingCommHttpsResourceModel{} - CommRsKeyRingCommHttpsList := make([]CommRsKeyRingCommHttpsResourceModel, 0) + CommRsClientCertCACommHttpsCommPol := CommRsClientCertCACommHttpsCommPolResourceModel{} + CommRsClientCertCACommHttpsCommPolList := make([]CommRsClientCertCACommHttpsCommPolResourceModel, 0) + TagAnnotationCommRsClientCertCACommHttpsCommPol := TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel{} + TagAnnotationCommRsClientCertCACommHttpsCommPolList := make([]TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel, 0) + TagTagCommRsClientCertCACommHttpsCommPol := TagTagCommRsClientCertCACommHttpsCommPolResourceModel{} + TagTagCommRsClientCertCACommHttpsCommPolList := make([]TagTagCommRsClientCertCACommHttpsCommPolResourceModel, 0) + CommRsKeyRingCommHttpsCommPol := CommRsKeyRingCommHttpsCommPolResourceModel{} + CommRsKeyRingCommHttpsCommPolList := make([]CommRsKeyRingCommHttpsCommPolResourceModel, 0) + TagAnnotationCommRsKeyRingCommHttpsCommPol := TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel{} + TagAnnotationCommRsKeyRingCommHttpsCommPolList := make([]TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel, 0) + TagTagCommRsKeyRingCommHttpsCommPol := TagTagCommRsKeyRingCommHttpsCommPolResourceModel{} + TagTagCommRsKeyRingCommHttpsCommPolList := make([]TagTagCommRsKeyRingCommHttpsCommPolResourceModel, 0) + TagAnnotationCommHttpsCommPol := TagAnnotationCommHttpsCommPolResourceModel{} + TagAnnotationCommHttpsCommPolList := make([]TagAnnotationCommHttpsCommPolResourceModel, 0) + TagTagCommHttpsCommPol := TagTagCommHttpsCommPolResourceModel{} + TagTagCommHttpsCommPolList := make([]TagTagCommHttpsCommPolResourceModel, 0) TagAnnotationCommPol := TagAnnotationCommPolResourceModel{} TagAnnotationCommPolList := make([]TagAnnotationCommPolResourceModel, 0) TagTagCommPol := TagTagCommPolResourceModel{} @@ -975,41 +1269,139 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl } } - childrenOfCommHttps, childrenOfCommHttpsExist := childClassDetails.(map[string]interface{})["children"] - if childrenOfCommHttpsExist { - for _, childCommHttps := range childrenOfCommHttps.([]interface{}) { - for childClassNameCommHttps, childClassDetailsCommHttps := range childCommHttps.(map[string]interface{}) { - if childClassNameCommHttps == "commRsClientCertCA" { - commRsClientCertCAchildAttributeValue := childClassDetailsCommHttps.(map[string]interface{})["attributes"].(map[string]interface{}) + childrenOfCommHttpsCommPol, childrenOfCommHttpsCommPolExist := childClassDetails.(map[string]interface{})["children"] + if childrenOfCommHttpsCommPolExist { + for _, childCommHttpsCommPol := range childrenOfCommHttpsCommPol.([]interface{}) { + for childClassNameCommHttpsCommPol, childClassDetailsCommHttpsCommPol := range childCommHttpsCommPol.(map[string]interface{}) { + if childClassNameCommHttpsCommPol == "commRsClientCertCA" { + commRsClientCertCAchildAttributeValue := childClassDetailsCommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) for childAttributeName, childAttributeValue := range commRsClientCertCAchildAttributeValue { if childAttributeName == "annotation" { - CommRsClientCertCACommHttps.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) + CommRsClientCertCACommHttpsCommPol.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) } if childAttributeName == "tDn" { - CommRsClientCertCACommHttps.TDn = basetypes.NewStringValue(childAttributeValue.(string)) + CommRsClientCertCACommHttpsCommPol.TDn = basetypes.NewStringValue(childAttributeValue.(string)) } } - CommRsClientCertCACommHttpsList = append(CommRsClientCertCACommHttpsList, CommRsClientCertCACommHttps) + childrenOfCommRsClientCertCACommHttpsCommPol, childrenOfCommRsClientCertCACommHttpsCommPolExist := childClassDetailsCommHttpsCommPol.(map[string]interface{})["children"] + if childrenOfCommRsClientCertCACommHttpsCommPolExist { + for _, childCommRsClientCertCACommHttpsCommPol := range childrenOfCommRsClientCertCACommHttpsCommPol.([]interface{}) { + for childClassNameCommRsClientCertCACommHttpsCommPol, childClassDetailsCommRsClientCertCACommHttpsCommPol := range childCommRsClientCertCACommHttpsCommPol.(map[string]interface{}) { + if childClassNameCommRsClientCertCACommHttpsCommPol == "tagAnnotation" { + tagAnnotationchildAttributeValue := childClassDetailsCommRsClientCertCACommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { + if childAttributeName == "key" { + TagAnnotationCommRsClientCertCACommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationCommRsClientCertCACommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagAnnotationCommRsClientCertCACommHttpsCommPolList = append(TagAnnotationCommRsClientCertCACommHttpsCommPolList, TagAnnotationCommRsClientCertCACommHttpsCommPol) + } + if childClassNameCommRsClientCertCACommHttpsCommPol == "tagTag" { + tagTagchildAttributeValue := childClassDetailsCommRsClientCertCACommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { + if childAttributeName == "key" { + TagTagCommRsClientCertCACommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagCommRsClientCertCACommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagTagCommRsClientCertCACommHttpsCommPolList = append(TagTagCommRsClientCertCACommHttpsCommPolList, TagTagCommRsClientCertCACommHttpsCommPol) + } + } + } + } + TagAnnotationSet, _ := types.SetValueFrom(ctx, TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModelElementType(), TagAnnotationCommRsClientCertCACommHttpsCommPolList) + CommRsClientCertCACommHttpsCommPol.TagAnnotation = TagAnnotationSet + TagTagSet, _ := types.SetValueFrom(ctx, TagTagCommRsClientCertCACommHttpsCommPolResourceModelElementType(), TagTagCommRsClientCertCACommHttpsCommPolList) + CommRsClientCertCACommHttpsCommPol.TagTag = TagTagSet + CommRsClientCertCACommHttpsCommPolList = append(CommRsClientCertCACommHttpsCommPolList, CommRsClientCertCACommHttpsCommPol) } - if childClassNameCommHttps == "commRsKeyRing" { - commRsKeyRingchildAttributeValue := childClassDetailsCommHttps.(map[string]interface{})["attributes"].(map[string]interface{}) + if childClassNameCommHttpsCommPol == "commRsKeyRing" { + commRsKeyRingchildAttributeValue := childClassDetailsCommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) for childAttributeName, childAttributeValue := range commRsKeyRingchildAttributeValue { if childAttributeName == "annotation" { - CommRsKeyRingCommHttps.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) + CommRsKeyRingCommHttpsCommPol.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) } if childAttributeName == "tnPkiKeyRingName" { - CommRsKeyRingCommHttps.TnPkiKeyRingName = basetypes.NewStringValue(childAttributeValue.(string)) + CommRsKeyRingCommHttpsCommPol.TnPkiKeyRingName = basetypes.NewStringValue(childAttributeValue.(string)) } } - CommRsKeyRingCommHttpsList = append(CommRsKeyRingCommHttpsList, CommRsKeyRingCommHttps) + childrenOfCommRsKeyRingCommHttpsCommPol, childrenOfCommRsKeyRingCommHttpsCommPolExist := childClassDetailsCommHttpsCommPol.(map[string]interface{})["children"] + if childrenOfCommRsKeyRingCommHttpsCommPolExist { + for _, childCommRsKeyRingCommHttpsCommPol := range childrenOfCommRsKeyRingCommHttpsCommPol.([]interface{}) { + for childClassNameCommRsKeyRingCommHttpsCommPol, childClassDetailsCommRsKeyRingCommHttpsCommPol := range childCommRsKeyRingCommHttpsCommPol.(map[string]interface{}) { + if childClassNameCommRsKeyRingCommHttpsCommPol == "tagAnnotation" { + tagAnnotationchildAttributeValue := childClassDetailsCommRsKeyRingCommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { + if childAttributeName == "key" { + TagAnnotationCommRsKeyRingCommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationCommRsKeyRingCommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagAnnotationCommRsKeyRingCommHttpsCommPolList = append(TagAnnotationCommRsKeyRingCommHttpsCommPolList, TagAnnotationCommRsKeyRingCommHttpsCommPol) + } + if childClassNameCommRsKeyRingCommHttpsCommPol == "tagTag" { + tagTagchildAttributeValue := childClassDetailsCommRsKeyRingCommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { + if childAttributeName == "key" { + TagTagCommRsKeyRingCommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagCommRsKeyRingCommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagTagCommRsKeyRingCommHttpsCommPolList = append(TagTagCommRsKeyRingCommHttpsCommPolList, TagTagCommRsKeyRingCommHttpsCommPol) + } + } + } + } + TagAnnotationSet, _ := types.SetValueFrom(ctx, TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModelElementType(), TagAnnotationCommRsKeyRingCommHttpsCommPolList) + CommRsKeyRingCommHttpsCommPol.TagAnnotation = TagAnnotationSet + TagTagSet, _ := types.SetValueFrom(ctx, TagTagCommRsKeyRingCommHttpsCommPolResourceModelElementType(), TagTagCommRsKeyRingCommHttpsCommPolList) + CommRsKeyRingCommHttpsCommPol.TagTag = TagTagSet + CommRsKeyRingCommHttpsCommPolList = append(CommRsKeyRingCommHttpsCommPolList, CommRsKeyRingCommHttpsCommPol) + } + if childClassNameCommHttpsCommPol == "tagAnnotation" { + tagAnnotationchildAttributeValue := childClassDetailsCommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { + if childAttributeName == "key" { + TagAnnotationCommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationCommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagAnnotationCommHttpsCommPolList = append(TagAnnotationCommHttpsCommPolList, TagAnnotationCommHttpsCommPol) + } + if childClassNameCommHttpsCommPol == "tagTag" { + tagTagchildAttributeValue := childClassDetailsCommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { + if childAttributeName == "key" { + TagTagCommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagCommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagTagCommHttpsCommPolList = append(TagTagCommHttpsCommPolList, TagTagCommHttpsCommPol) } } } } - CommRsClientCertCASet, _ := types.SetValueFrom(ctx, CommRsClientCertCACommHttpsResourceModelElementType(), CommRsClientCertCACommHttpsList) + CommRsClientCertCASet, _ := types.SetValueFrom(ctx, CommRsClientCertCACommHttpsCommPolResourceModelElementType(), CommRsClientCertCACommHttpsCommPolList) CommHttpsCommPol.CommRsClientCertCA = CommRsClientCertCASet - CommRsKeyRingSet, _ := types.SetValueFrom(ctx, CommRsKeyRingCommHttpsResourceModelElementType(), CommRsKeyRingCommHttpsList) + CommRsKeyRingSet, _ := types.SetValueFrom(ctx, CommRsKeyRingCommHttpsCommPolResourceModelElementType(), CommRsKeyRingCommHttpsCommPolList) CommHttpsCommPol.CommRsKeyRing = CommRsKeyRingSet + TagAnnotationSet, _ := types.SetValueFrom(ctx, TagAnnotationCommHttpsCommPolResourceModelElementType(), TagAnnotationCommHttpsCommPolList) + CommHttpsCommPol.TagAnnotation = TagAnnotationSet + TagTagSet, _ := types.SetValueFrom(ctx, TagTagCommHttpsCommPolResourceModelElementType(), TagTagCommHttpsCommPolList) + CommHttpsCommPol.TagTag = TagTagSet CommHttpsCommPolList = append(CommHttpsCommPolList, CommHttpsCommPol) } if childClassName == "tagAnnotation" { @@ -1071,112 +1463,162 @@ func setCommPolId(ctx context.Context, data *CommPolResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", strings.Split([]string{"uni/fabric/comm-{name}"}[0], "/")[0], rn)) } -func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, commHttpsPlan, commHttpsState []CommHttpsCommPolResourceModel) []map[string]interface{} { +func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, commHttpsCommPolPlan, commHttpsCommPolState []CommHttpsCommPolResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} - commRsClientCertCAChildMap := NewAciObject() - commRsKeyRingChildMap := NewAciObject() - CommHttpsChildren := make([]map[string]interface{}, 0) + commRsClientCertCACommHttpsCommPolChildMap := NewAciObject() + tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap := NewAciObject() + tagTagCommRsClientCertCACommHttpsCommPolChildMap := NewAciObject() + CommRsClientCertCACommHttpsCommPolChildren := make([]map[string]interface{}, 0) + commRsKeyRingCommHttpsCommPolChildMap := NewAciObject() + tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap := NewAciObject() + tagTagCommRsKeyRingCommHttpsCommPolChildMap := NewAciObject() + CommRsKeyRingCommHttpsCommPolChildren := make([]map[string]interface{}, 0) + tagAnnotationCommHttpsCommPolChildMap := NewAciObject() + tagTagCommHttpsCommPolChildMap := NewAciObject() + CommHttpsCommPolChildren := make([]map[string]interface{}, 0) if !data.CommHttps.IsNull() && !data.CommHttps.IsUnknown() { - for _, commHttps := range commHttpsPlan { - if !commHttps.AccessControlAllowCredential.IsNull() && !commHttps.AccessControlAllowCredential.IsUnknown() { - childMap.Attributes["accessControlAllowCredential"] = commHttps.AccessControlAllowCredential.ValueString() + for _, commHttpsCommPol := range commHttpsCommPolPlan { + if !commHttpsCommPol.AccessControlAllowCredential.IsNull() && !commHttpsCommPol.AccessControlAllowCredential.IsUnknown() { + childMap.Attributes["accessControlAllowCredential"] = commHttpsCommPol.AccessControlAllowCredential.ValueString() } - if !commHttps.AccessControlAllowOrigins.IsNull() && !commHttps.AccessControlAllowOrigins.IsUnknown() { - childMap.Attributes["accessControlAllowOrigins"] = commHttps.AccessControlAllowOrigins.ValueString() + if !commHttpsCommPol.AccessControlAllowOrigins.IsNull() && !commHttpsCommPol.AccessControlAllowOrigins.IsUnknown() { + childMap.Attributes["accessControlAllowOrigins"] = commHttpsCommPol.AccessControlAllowOrigins.ValueString() } - if !commHttps.AdminSt.IsNull() && !commHttps.AdminSt.IsUnknown() { - childMap.Attributes["adminSt"] = commHttps.AdminSt.ValueString() + if !commHttpsCommPol.AdminSt.IsNull() && !commHttpsCommPol.AdminSt.IsUnknown() { + childMap.Attributes["adminSt"] = commHttpsCommPol.AdminSt.ValueString() } - if !commHttps.Annotation.IsNull() && !commHttps.Annotation.IsUnknown() { - childMap.Attributes["annotation"] = commHttps.Annotation.ValueString() + if !commHttpsCommPol.Annotation.IsNull() && !commHttpsCommPol.Annotation.IsUnknown() { + childMap.Attributes["annotation"] = commHttpsCommPol.Annotation.ValueString() } else { childMap.Attributes["annotation"] = globalAnnotation } - if !commHttps.CliOnlyMode.IsNull() && !commHttps.CliOnlyMode.IsUnknown() { - childMap.Attributes["cliOnlyMode"] = commHttps.CliOnlyMode.ValueString() + if !commHttpsCommPol.CliOnlyMode.IsNull() && !commHttpsCommPol.CliOnlyMode.IsUnknown() { + childMap.Attributes["cliOnlyMode"] = commHttpsCommPol.CliOnlyMode.ValueString() } - if !commHttps.ClientCertAuthState.IsNull() && !commHttps.ClientCertAuthState.IsUnknown() { - childMap.Attributes["clientCertAuthState"] = commHttps.ClientCertAuthState.ValueString() + if !commHttpsCommPol.ClientCertAuthState.IsNull() && !commHttpsCommPol.ClientCertAuthState.IsUnknown() { + childMap.Attributes["clientCertAuthState"] = commHttpsCommPol.ClientCertAuthState.ValueString() } - if !commHttps.Descr.IsNull() && !commHttps.Descr.IsUnknown() { - childMap.Attributes["descr"] = commHttps.Descr.ValueString() + if !commHttpsCommPol.Descr.IsNull() && !commHttpsCommPol.Descr.IsUnknown() { + childMap.Attributes["descr"] = commHttpsCommPol.Descr.ValueString() } - if !commHttps.DhParam.IsNull() && !commHttps.DhParam.IsUnknown() { - childMap.Attributes["dhParam"] = commHttps.DhParam.ValueString() + if !commHttpsCommPol.DhParam.IsNull() && !commHttpsCommPol.DhParam.IsUnknown() { + childMap.Attributes["dhParam"] = commHttpsCommPol.DhParam.ValueString() } - if !commHttps.GlobalThrottleRate.IsNull() && !commHttps.GlobalThrottleRate.IsUnknown() { - childMap.Attributes["globalThrottleRate"] = commHttps.GlobalThrottleRate.ValueString() + if !commHttpsCommPol.GlobalThrottleRate.IsNull() && !commHttpsCommPol.GlobalThrottleRate.IsUnknown() { + childMap.Attributes["globalThrottleRate"] = commHttpsCommPol.GlobalThrottleRate.ValueString() } - if !commHttps.GlobalThrottleSt.IsNull() && !commHttps.GlobalThrottleSt.IsUnknown() { - childMap.Attributes["globalThrottleSt"] = commHttps.GlobalThrottleSt.ValueString() + if !commHttpsCommPol.GlobalThrottleSt.IsNull() && !commHttpsCommPol.GlobalThrottleSt.IsUnknown() { + childMap.Attributes["globalThrottleSt"] = commHttpsCommPol.GlobalThrottleSt.ValueString() } - if !commHttps.GlobalThrottleUnit.IsNull() && !commHttps.GlobalThrottleUnit.IsUnknown() { - childMap.Attributes["globalThrottleUnit"] = commHttps.GlobalThrottleUnit.ValueString() + if !commHttpsCommPol.GlobalThrottleUnit.IsNull() && !commHttpsCommPol.GlobalThrottleUnit.IsUnknown() { + childMap.Attributes["globalThrottleUnit"] = commHttpsCommPol.GlobalThrottleUnit.ValueString() } - if !commHttps.MaxRequestStatusCount.IsNull() && !commHttps.MaxRequestStatusCount.IsUnknown() { - childMap.Attributes["maxRequestStatusCount"] = commHttps.MaxRequestStatusCount.ValueString() + if !commHttpsCommPol.MaxRequestStatusCount.IsNull() && !commHttpsCommPol.MaxRequestStatusCount.IsUnknown() { + childMap.Attributes["maxRequestStatusCount"] = commHttpsCommPol.MaxRequestStatusCount.ValueString() } - if !commHttps.Name.IsNull() && !commHttps.Name.IsUnknown() { - childMap.Attributes["name"] = commHttps.Name.ValueString() + if !commHttpsCommPol.Name.IsNull() && !commHttpsCommPol.Name.IsUnknown() { + childMap.Attributes["name"] = commHttpsCommPol.Name.ValueString() } - if !commHttps.NameAlias.IsNull() && !commHttps.NameAlias.IsUnknown() { - childMap.Attributes["nameAlias"] = commHttps.NameAlias.ValueString() + if !commHttpsCommPol.NameAlias.IsNull() && !commHttpsCommPol.NameAlias.IsUnknown() { + childMap.Attributes["nameAlias"] = commHttpsCommPol.NameAlias.ValueString() } - if !commHttps.NodeExporter.IsNull() && !commHttps.NodeExporter.IsUnknown() { - childMap.Attributes["nodeExporter"] = commHttps.NodeExporter.ValueString() + if !commHttpsCommPol.NodeExporter.IsNull() && !commHttpsCommPol.NodeExporter.IsUnknown() { + childMap.Attributes["nodeExporter"] = commHttpsCommPol.NodeExporter.ValueString() } - if !commHttps.Port.IsNull() && !commHttps.Port.IsUnknown() { - childMap.Attributes["port"] = commHttps.Port.ValueString() + if !commHttpsCommPol.Port.IsNull() && !commHttpsCommPol.Port.IsUnknown() { + childMap.Attributes["port"] = commHttpsCommPol.Port.ValueString() } - if !commHttps.Referer.IsNull() && !commHttps.Referer.IsUnknown() { - childMap.Attributes["referer"] = commHttps.Referer.ValueString() + if !commHttpsCommPol.Referer.IsNull() && !commHttpsCommPol.Referer.IsUnknown() { + childMap.Attributes["referer"] = commHttpsCommPol.Referer.ValueString() } - if !commHttps.ServerHeader.IsNull() && !commHttps.ServerHeader.IsUnknown() { - childMap.Attributes["serverHeader"] = commHttps.ServerHeader.ValueString() + if !commHttpsCommPol.ServerHeader.IsNull() && !commHttpsCommPol.ServerHeader.IsUnknown() { + childMap.Attributes["serverHeader"] = commHttpsCommPol.ServerHeader.ValueString() } - if !commHttps.SslProtocols.IsNull() && !commHttps.SslProtocols.IsUnknown() { + if !commHttpsCommPol.SslProtocols.IsNull() && !commHttpsCommPol.SslProtocols.IsUnknown() { var tmpSslProtocols []string - commHttps.SslProtocols.ElementsAs(ctx, &tmpSslProtocols, false) + commHttpsCommPol.SslProtocols.ElementsAs(ctx, &tmpSslProtocols, false) childMap.Attributes["sslProtocols"] = strings.Join(tmpSslProtocols, ",") } - if !commHttps.ThrottleRate.IsNull() && !commHttps.ThrottleRate.IsUnknown() { - childMap.Attributes["throttleRate"] = commHttps.ThrottleRate.ValueString() + if !commHttpsCommPol.ThrottleRate.IsNull() && !commHttpsCommPol.ThrottleRate.IsUnknown() { + childMap.Attributes["throttleRate"] = commHttpsCommPol.ThrottleRate.ValueString() } - if !commHttps.ThrottleSt.IsNull() && !commHttps.ThrottleSt.IsUnknown() { - childMap.Attributes["throttleSt"] = commHttps.ThrottleSt.ValueString() + if !commHttpsCommPol.ThrottleSt.IsNull() && !commHttpsCommPol.ThrottleSt.IsUnknown() { + childMap.Attributes["throttleSt"] = commHttpsCommPol.ThrottleSt.ValueString() } - if !commHttps.VisoreAccess.IsNull() && !commHttps.VisoreAccess.IsUnknown() { - childMap.Attributes["visoreAccess"] = commHttps.VisoreAccess.ValueString() + if !commHttpsCommPol.VisoreAccess.IsNull() && !commHttpsCommPol.VisoreAccess.IsUnknown() { + childMap.Attributes["visoreAccess"] = commHttpsCommPol.VisoreAccess.ValueString() } - var commRsClientCertCAPlan, commRsClientCertCAState []CommRsClientCertCACommHttpsResourceModel - commHttps.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCAPlan, false) - for _, commHttpscommRsClientCertCAState := range commHttpsState { - commHttpscommRsClientCertCAState.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCAState, false) - if len(commRsClientCertCAPlan) == 0 && len(commRsClientCertCAState) == 1 { - commRsClientCertCAChildMap := NewAciObject() - commRsClientCertCAChildMap.Attributes["status"] = "deleted" - CommHttpsChildren = append(CommHttpsChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCAChildMap}) + var commRsClientCertCACommHttpsCommPolPlan, commRsClientCertCACommHttpsCommPolState []CommRsClientCertCACommHttpsCommPolResourceModel + commHttpsCommPol.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCACommHttpsCommPolPlan, false) + for _, commHttpscommRsClientCertCAState := range commHttpsCommPolState { + commHttpscommRsClientCertCAState.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCACommHttpsCommPolState, false) + if len(commRsClientCertCACommHttpsCommPolPlan) == 0 && len(commRsClientCertCACommHttpsCommPolState) == 1 { + commRsClientCertCACommHttpsCommPolChildMap := NewAciObject() + commRsClientCertCACommHttpsCommPolChildMap.Attributes["status"] = "deleted" + CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCACommHttpsCommPolChildMap}) } } - if !commHttps.CommRsClientCertCA.IsNull() && !commHttps.CommRsClientCertCA.IsUnknown() { - for _, commRsClientCertCA := range commRsClientCertCAPlan { - if !commRsClientCertCA.Annotation.IsNull() && !commRsClientCertCA.Annotation.IsUnknown() { - commRsClientCertCAChildMap.Attributes["annotation"] = commRsClientCertCA.Annotation.ValueString() + if !commHttpsCommPol.CommRsClientCertCA.IsNull() && !commHttpsCommPol.CommRsClientCertCA.IsUnknown() { + for _, commRsClientCertCACommHttpsCommPol := range commRsClientCertCACommHttpsCommPolPlan { + if !commRsClientCertCACommHttpsCommPol.Annotation.IsNull() && !commRsClientCertCACommHttpsCommPol.Annotation.IsUnknown() { + commRsClientCertCACommHttpsCommPolChildMap.Attributes["annotation"] = commRsClientCertCACommHttpsCommPol.Annotation.ValueString() } else { - commRsClientCertCAChildMap.Attributes["annotation"] = globalAnnotation + commRsClientCertCACommHttpsCommPolChildMap.Attributes["annotation"] = globalAnnotation + } + if !commRsClientCertCACommHttpsCommPol.TDn.IsNull() && !commRsClientCertCACommHttpsCommPol.TDn.IsUnknown() { + commRsClientCertCACommHttpsCommPolChildMap.Attributes["tDn"] = commRsClientCertCACommHttpsCommPol.TDn.ValueString() + } + var tagAnnotationCommRsClientCertCACommHttpsCommPolPlan, tagAnnotationCommRsClientCertCACommHttpsCommPolState []TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel + commRsClientCertCACommHttpsCommPol.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommRsClientCertCACommHttpsCommPolPlan, false) + for _, commRsClientCertCAtagAnnotationState := range commRsClientCertCACommHttpsCommPolState { + commRsClientCertCAtagAnnotationState.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommRsClientCertCACommHttpsCommPolState, false) + if len(tagAnnotationCommRsClientCertCACommHttpsCommPolPlan) == 0 && len(tagAnnotationCommRsClientCertCACommHttpsCommPolState) == 1 { + tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap := NewAciObject() + tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap.Attributes["status"] = "deleted" + CommRsClientCertCACommHttpsCommPolChildren = append(CommRsClientCertCACommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap}) + } + } + if !commRsClientCertCACommHttpsCommPol.TagAnnotation.IsNull() && !commRsClientCertCACommHttpsCommPol.TagAnnotation.IsUnknown() { + for _, tagAnnotationCommRsClientCertCACommHttpsCommPol := range tagAnnotationCommRsClientCertCACommHttpsCommPolPlan { + if !tagAnnotationCommRsClientCertCACommHttpsCommPol.Key.IsNull() && !tagAnnotationCommRsClientCertCACommHttpsCommPol.Key.IsUnknown() { + tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap.Attributes["key"] = tagAnnotationCommRsClientCertCACommHttpsCommPol.Key.ValueString() + } + if !tagAnnotationCommRsClientCertCACommHttpsCommPol.Value.IsNull() && !tagAnnotationCommRsClientCertCACommHttpsCommPol.Value.IsUnknown() { + tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap.Attributes["value"] = tagAnnotationCommRsClientCertCACommHttpsCommPol.Value.ValueString() + } + CommRsClientCertCACommHttpsCommPolChildren = append(CommRsClientCertCACommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap}) + } } - if !commRsClientCertCA.TDn.IsNull() && !commRsClientCertCA.TDn.IsUnknown() { - commRsClientCertCAChildMap.Attributes["tDn"] = commRsClientCertCA.TDn.ValueString() + var tagTagCommRsClientCertCACommHttpsCommPolPlan, tagTagCommRsClientCertCACommHttpsCommPolState []TagTagCommRsClientCertCACommHttpsCommPolResourceModel + commRsClientCertCACommHttpsCommPol.TagTag.ElementsAs(ctx, &tagTagCommRsClientCertCACommHttpsCommPolPlan, false) + for _, commRsClientCertCAtagTagState := range commRsClientCertCACommHttpsCommPolState { + commRsClientCertCAtagTagState.TagTag.ElementsAs(ctx, &tagTagCommRsClientCertCACommHttpsCommPolState, false) + if len(tagTagCommRsClientCertCACommHttpsCommPolPlan) == 0 && len(tagTagCommRsClientCertCACommHttpsCommPolState) == 1 { + tagTagCommRsClientCertCACommHttpsCommPolChildMap := NewAciObject() + tagTagCommRsClientCertCACommHttpsCommPolChildMap.Attributes["status"] = "deleted" + CommRsClientCertCACommHttpsCommPolChildren = append(CommRsClientCertCACommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommRsClientCertCACommHttpsCommPolChildMap}) + } } - CommHttpsChildren = append(CommHttpsChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCAChildMap}) + if !commRsClientCertCACommHttpsCommPol.TagTag.IsNull() && !commRsClientCertCACommHttpsCommPol.TagTag.IsUnknown() { + for _, tagTagCommRsClientCertCACommHttpsCommPol := range tagTagCommRsClientCertCACommHttpsCommPolPlan { + if !tagTagCommRsClientCertCACommHttpsCommPol.Key.IsNull() && !tagTagCommRsClientCertCACommHttpsCommPol.Key.IsUnknown() { + tagTagCommRsClientCertCACommHttpsCommPolChildMap.Attributes["key"] = tagTagCommRsClientCertCACommHttpsCommPol.Key.ValueString() + } + if !tagTagCommRsClientCertCACommHttpsCommPol.Value.IsNull() && !tagTagCommRsClientCertCACommHttpsCommPol.Value.IsUnknown() { + tagTagCommRsClientCertCACommHttpsCommPolChildMap.Attributes["value"] = tagTagCommRsClientCertCACommHttpsCommPol.Value.ValueString() + } + CommRsClientCertCACommHttpsCommPolChildren = append(CommRsClientCertCACommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommRsClientCertCACommHttpsCommPolChildMap}) + } + } + CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCACommHttpsCommPolChildMap}) } } - var commRsKeyRingPlan, commRsKeyRingState []CommRsKeyRingCommHttpsResourceModel - commHttps.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingPlan, false) - for _, commHttpscommRsKeyRingState := range commHttpsState { - commHttpscommRsKeyRingState.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingState, false) - if len(commRsKeyRingPlan) == 0 && len(commRsKeyRingState) == 1 { + var commRsKeyRingCommHttpsCommPolPlan, commRsKeyRingCommHttpsCommPolState []CommRsKeyRingCommHttpsCommPolResourceModel + commHttpsCommPol.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingCommHttpsCommPolPlan, false) + for _, commHttpscommRsKeyRingState := range commHttpsCommPolState { + commHttpscommRsKeyRingState.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingCommHttpsCommPolState, false) + if len(commRsKeyRingCommHttpsCommPolPlan) == 0 && len(commRsKeyRingCommHttpsCommPolState) == 1 { diags.AddError( "CommRsKeyRing object cannot be deleted", "deletion of child is only possible upon deletion of the parent", @@ -1184,23 +1626,107 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti return nil } } - if !commHttps.CommRsKeyRing.IsNull() && !commHttps.CommRsKeyRing.IsUnknown() { - for _, commRsKeyRing := range commRsKeyRingPlan { - if !commRsKeyRing.Annotation.IsNull() && !commRsKeyRing.Annotation.IsUnknown() { - commRsKeyRingChildMap.Attributes["annotation"] = commRsKeyRing.Annotation.ValueString() + if !commHttpsCommPol.CommRsKeyRing.IsNull() && !commHttpsCommPol.CommRsKeyRing.IsUnknown() { + for _, commRsKeyRingCommHttpsCommPol := range commRsKeyRingCommHttpsCommPolPlan { + if !commRsKeyRingCommHttpsCommPol.Annotation.IsNull() && !commRsKeyRingCommHttpsCommPol.Annotation.IsUnknown() { + commRsKeyRingCommHttpsCommPolChildMap.Attributes["annotation"] = commRsKeyRingCommHttpsCommPol.Annotation.ValueString() } else { - commRsKeyRingChildMap.Attributes["annotation"] = globalAnnotation + commRsKeyRingCommHttpsCommPolChildMap.Attributes["annotation"] = globalAnnotation + } + if !commRsKeyRingCommHttpsCommPol.TnPkiKeyRingName.IsNull() && !commRsKeyRingCommHttpsCommPol.TnPkiKeyRingName.IsUnknown() { + commRsKeyRingCommHttpsCommPolChildMap.Attributes["tnPkiKeyRingName"] = commRsKeyRingCommHttpsCommPol.TnPkiKeyRingName.ValueString() + } + var tagAnnotationCommRsKeyRingCommHttpsCommPolPlan, tagAnnotationCommRsKeyRingCommHttpsCommPolState []TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel + commRsKeyRingCommHttpsCommPol.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommRsKeyRingCommHttpsCommPolPlan, false) + for _, commRsKeyRingtagAnnotationState := range commRsKeyRingCommHttpsCommPolState { + commRsKeyRingtagAnnotationState.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommRsKeyRingCommHttpsCommPolState, false) + if len(tagAnnotationCommRsKeyRingCommHttpsCommPolPlan) == 0 && len(tagAnnotationCommRsKeyRingCommHttpsCommPolState) == 1 { + tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap := NewAciObject() + tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap.Attributes["status"] = "deleted" + CommRsKeyRingCommHttpsCommPolChildren = append(CommRsKeyRingCommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap}) + } + } + if !commRsKeyRingCommHttpsCommPol.TagAnnotation.IsNull() && !commRsKeyRingCommHttpsCommPol.TagAnnotation.IsUnknown() { + for _, tagAnnotationCommRsKeyRingCommHttpsCommPol := range tagAnnotationCommRsKeyRingCommHttpsCommPolPlan { + if !tagAnnotationCommRsKeyRingCommHttpsCommPol.Key.IsNull() && !tagAnnotationCommRsKeyRingCommHttpsCommPol.Key.IsUnknown() { + tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap.Attributes["key"] = tagAnnotationCommRsKeyRingCommHttpsCommPol.Key.ValueString() + } + if !tagAnnotationCommRsKeyRingCommHttpsCommPol.Value.IsNull() && !tagAnnotationCommRsKeyRingCommHttpsCommPol.Value.IsUnknown() { + tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap.Attributes["value"] = tagAnnotationCommRsKeyRingCommHttpsCommPol.Value.ValueString() + } + CommRsKeyRingCommHttpsCommPolChildren = append(CommRsKeyRingCommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap}) + } + } + var tagTagCommRsKeyRingCommHttpsCommPolPlan, tagTagCommRsKeyRingCommHttpsCommPolState []TagTagCommRsKeyRingCommHttpsCommPolResourceModel + commRsKeyRingCommHttpsCommPol.TagTag.ElementsAs(ctx, &tagTagCommRsKeyRingCommHttpsCommPolPlan, false) + for _, commRsKeyRingtagTagState := range commRsKeyRingCommHttpsCommPolState { + commRsKeyRingtagTagState.TagTag.ElementsAs(ctx, &tagTagCommRsKeyRingCommHttpsCommPolState, false) + if len(tagTagCommRsKeyRingCommHttpsCommPolPlan) == 0 && len(tagTagCommRsKeyRingCommHttpsCommPolState) == 1 { + tagTagCommRsKeyRingCommHttpsCommPolChildMap := NewAciObject() + tagTagCommRsKeyRingCommHttpsCommPolChildMap.Attributes["status"] = "deleted" + CommRsKeyRingCommHttpsCommPolChildren = append(CommRsKeyRingCommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommRsKeyRingCommHttpsCommPolChildMap}) + } + } + if !commRsKeyRingCommHttpsCommPol.TagTag.IsNull() && !commRsKeyRingCommHttpsCommPol.TagTag.IsUnknown() { + for _, tagTagCommRsKeyRingCommHttpsCommPol := range tagTagCommRsKeyRingCommHttpsCommPolPlan { + if !tagTagCommRsKeyRingCommHttpsCommPol.Key.IsNull() && !tagTagCommRsKeyRingCommHttpsCommPol.Key.IsUnknown() { + tagTagCommRsKeyRingCommHttpsCommPolChildMap.Attributes["key"] = tagTagCommRsKeyRingCommHttpsCommPol.Key.ValueString() + } + if !tagTagCommRsKeyRingCommHttpsCommPol.Value.IsNull() && !tagTagCommRsKeyRingCommHttpsCommPol.Value.IsUnknown() { + tagTagCommRsKeyRingCommHttpsCommPolChildMap.Attributes["value"] = tagTagCommRsKeyRingCommHttpsCommPol.Value.ValueString() + } + CommRsKeyRingCommHttpsCommPolChildren = append(CommRsKeyRingCommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommRsKeyRingCommHttpsCommPolChildMap}) + } + } + CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"commRsKeyRing": commRsKeyRingCommHttpsCommPolChildMap}) + } + } + var tagAnnotationCommHttpsCommPolPlan, tagAnnotationCommHttpsCommPolState []TagAnnotationCommHttpsCommPolResourceModel + commHttpsCommPol.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommHttpsCommPolPlan, false) + for _, commHttpstagAnnotationState := range commHttpsCommPolState { + commHttpstagAnnotationState.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommHttpsCommPolState, false) + if len(tagAnnotationCommHttpsCommPolPlan) == 0 && len(tagAnnotationCommHttpsCommPolState) == 1 { + tagAnnotationCommHttpsCommPolChildMap := NewAciObject() + tagAnnotationCommHttpsCommPolChildMap.Attributes["status"] = "deleted" + CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommHttpsCommPolChildMap}) + } + } + if !commHttpsCommPol.TagAnnotation.IsNull() && !commHttpsCommPol.TagAnnotation.IsUnknown() { + for _, tagAnnotationCommHttpsCommPol := range tagAnnotationCommHttpsCommPolPlan { + if !tagAnnotationCommHttpsCommPol.Key.IsNull() && !tagAnnotationCommHttpsCommPol.Key.IsUnknown() { + tagAnnotationCommHttpsCommPolChildMap.Attributes["key"] = tagAnnotationCommHttpsCommPol.Key.ValueString() + } + if !tagAnnotationCommHttpsCommPol.Value.IsNull() && !tagAnnotationCommHttpsCommPol.Value.IsUnknown() { + tagAnnotationCommHttpsCommPolChildMap.Attributes["value"] = tagAnnotationCommHttpsCommPol.Value.ValueString() + } + CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommHttpsCommPolChildMap}) + } + } + var tagTagCommHttpsCommPolPlan, tagTagCommHttpsCommPolState []TagTagCommHttpsCommPolResourceModel + commHttpsCommPol.TagTag.ElementsAs(ctx, &tagTagCommHttpsCommPolPlan, false) + for _, commHttpstagTagState := range commHttpsCommPolState { + commHttpstagTagState.TagTag.ElementsAs(ctx, &tagTagCommHttpsCommPolState, false) + if len(tagTagCommHttpsCommPolPlan) == 0 && len(tagTagCommHttpsCommPolState) == 1 { + tagTagCommHttpsCommPolChildMap := NewAciObject() + tagTagCommHttpsCommPolChildMap.Attributes["status"] = "deleted" + CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommHttpsCommPolChildMap}) + } + } + if !commHttpsCommPol.TagTag.IsNull() && !commHttpsCommPol.TagTag.IsUnknown() { + for _, tagTagCommHttpsCommPol := range tagTagCommHttpsCommPolPlan { + if !tagTagCommHttpsCommPol.Key.IsNull() && !tagTagCommHttpsCommPol.Key.IsUnknown() { + tagTagCommHttpsCommPolChildMap.Attributes["key"] = tagTagCommHttpsCommPol.Key.ValueString() } - if !commRsKeyRing.TnPkiKeyRingName.IsNull() && !commRsKeyRing.TnPkiKeyRingName.IsUnknown() { - commRsKeyRingChildMap.Attributes["tnPkiKeyRingName"] = commRsKeyRing.TnPkiKeyRingName.ValueString() + if !tagTagCommHttpsCommPol.Value.IsNull() && !tagTagCommHttpsCommPol.Value.IsUnknown() { + tagTagCommHttpsCommPolChildMap.Attributes["value"] = tagTagCommHttpsCommPol.Value.ValueString() } - CommHttpsChildren = append(CommHttpsChildren, map[string]interface{}{"commRsKeyRing": commRsKeyRingChildMap}) + CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommHttpsCommPolChildMap}) } } - childMap.Children = CommHttpsChildren + childMap.Children = CommHttpsCommPolChildren childPayloads = append(childPayloads, map[string]interface{}{"commHttps": childMap}) } - if len(commHttpsPlan) == 0 && len(commHttpsState) == 1 { + if len(commHttpsCommPolPlan) == 0 && len(commHttpsCommPolState) == 1 { diags.AddError( "CommHttps object cannot be deleted", "deletion of child is only possible upon deletion of the parent", @@ -1214,24 +1740,24 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti return childPayloads } -func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationCommPolResourceModel) []map[string]interface{} { +func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, tagAnnotationCommPolPlan, tagAnnotationCommPolState []TagAnnotationCommPolResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationCommPol := range tagAnnotationCommPolPlan { + if !tagAnnotationCommPol.Key.IsNull() && !tagAnnotationCommPol.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationCommPol.Key.ValueString() } - if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationCommPol.Value.IsNull() && !tagAnnotationCommPol.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationCommPol.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationCommPol.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationCommPolState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -1253,24 +1779,24 @@ func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagn return childPayloads } -func getCommPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, tagTagPlan, tagTagState []TagTagCommPolResourceModel) []map[string]interface{} { +func getCommPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, tagTagCommPolPlan, tagTagCommPolState []TagTagCommPolResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagTag.Key.ValueString() + for _, tagTagCommPol := range tagTagCommPolPlan { + if !tagTagCommPol.Key.IsNull() && !tagTagCommPol.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagCommPol.Key.ValueString() } - if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagTag.Value.ValueString() + if !tagTagCommPol.Value.IsNull() && !tagTagCommPol.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagCommPol.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagCommPol.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagCommPolState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { diff --git a/internal/provider/resource_aci_communication_policy_test.go b/internal/provider/resource_aci_communication_policy_test.go index 31b73fedd..da7b97f6d 100644 --- a/internal/provider/resource_aci_communication_policy_test.go +++ b/internal/provider/resource_aci_communication_policy_test.go @@ -93,9 +93,9 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_key", ""), resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_tag", ""), resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "false"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.key", "annotations_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.key", "key_0"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.1.key", "annotations_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.1.key", "key_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.1.value", "value_2"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.#", "2"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_credential", "disabled"), @@ -143,9 +143,9 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.throttle_st", "enabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.visore_access", "enabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "tags_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.1.key", "tags_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.1.key", "key_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.1.value", "value_2"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.#", "2"), ), @@ -160,9 +160,9 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_key", ""), resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_tag", ""), resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "false"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.key", "annotations_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.key", "key_0"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.1.key", "annotations_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.1.key", "key_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.1.value", "value_2"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.#", "2"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_credential", "disabled"), @@ -210,9 +210,9 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.throttle_st", "enabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.visore_access", "enabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "tags_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.1.key", "tags_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.1.key", "key_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.1.value", "value_2"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.#", "2"), ), @@ -227,7 +227,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_key", ""), resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_tag", ""), resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "false"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.key", "annotations_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.#", "1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_credential", "enabled"), @@ -253,7 +253,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "enabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "enabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "tags_2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.#", "1"), ), @@ -311,11 +311,11 @@ resource "aci_communication_policy" "test" { name = "test_name" annotations = [ { - key = "annotations_1" + key = "key_0" value = "value_1" }, { - key = "annotations_2" + key = "key_1" value = "value_2" }, ] @@ -371,11 +371,11 @@ resource "aci_communication_policy" "test" { ] tags = [ { - key = "tags_1" + key = "key_0" value = "value_1" }, { - key = "tags_2" + key = "key_1" value = "value_2" }, ] @@ -393,7 +393,7 @@ resource "aci_communication_policy" "test" { name = "test_name" annotations = [ { - key = "annotations_2" + key = "key_1" value = "value_2" }, ] @@ -425,7 +425,7 @@ resource "aci_communication_policy" "test" { ] tags = [ { - key = "tags_2" + key = "key_1" value = "value_2" }, ] diff --git a/internal/provider/resource_aci_endpoint_tag_ip.go b/internal/provider/resource_aci_endpoint_tag_ip.go index 95b907ed7..d760f7610 100644 --- a/internal/provider/resource_aci_endpoint_tag_ip.go +++ b/internal/provider/resource_aci_endpoint_tag_ip.go @@ -541,24 +541,24 @@ func setFvEpIpTagId(ctx context.Context, data *FvEpIpTagResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getFvEpIpTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpIpTagResourceModel) []map[string]interface{} { +func getFvEpIpTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagAnnotationFvEpIpTagPlan, tagAnnotationFvEpIpTagState []TagAnnotationFvEpIpTagResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationFvEpIpTag := range tagAnnotationFvEpIpTagPlan { + if !tagAnnotationFvEpIpTag.Key.IsNull() && !tagAnnotationFvEpIpTag.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationFvEpIpTag.Key.ValueString() } - if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationFvEpIpTag.Value.IsNull() && !tagAnnotationFvEpIpTag.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationFvEpIpTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationFvEpIpTag.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationFvEpIpTagState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -580,24 +580,24 @@ func getFvEpIpTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia return childPayloads } -func getFvEpIpTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagTagPlan, tagTagState []TagTagFvEpIpTagResourceModel) []map[string]interface{} { +func getFvEpIpTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagTagFvEpIpTagPlan, tagTagFvEpIpTagState []TagTagFvEpIpTagResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagTag.Key.ValueString() + for _, tagTagFvEpIpTag := range tagTagFvEpIpTagPlan { + if !tagTagFvEpIpTag.Key.IsNull() && !tagTagFvEpIpTag.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagFvEpIpTag.Key.ValueString() } - if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagTag.Value.ValueString() + if !tagTagFvEpIpTag.Value.IsNull() && !tagTagFvEpIpTag.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagFvEpIpTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagFvEpIpTag.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagFvEpIpTagState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { diff --git a/internal/provider/resource_aci_endpoint_tag_mac.go b/internal/provider/resource_aci_endpoint_tag_mac.go index fa03827e6..6f119db10 100644 --- a/internal/provider/resource_aci_endpoint_tag_mac.go +++ b/internal/provider/resource_aci_endpoint_tag_mac.go @@ -541,24 +541,24 @@ func setFvEpMacTagId(ctx context.Context, data *FvEpMacTagResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getFvEpMacTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpMacTagResourceModel) []map[string]interface{} { +func getFvEpMacTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagAnnotationFvEpMacTagPlan, tagAnnotationFvEpMacTagState []TagAnnotationFvEpMacTagResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationFvEpMacTag := range tagAnnotationFvEpMacTagPlan { + if !tagAnnotationFvEpMacTag.Key.IsNull() && !tagAnnotationFvEpMacTag.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationFvEpMacTag.Key.ValueString() } - if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationFvEpMacTag.Value.IsNull() && !tagAnnotationFvEpMacTag.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationFvEpMacTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationFvEpMacTag.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationFvEpMacTagState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -580,24 +580,24 @@ func getFvEpMacTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di return childPayloads } -func getFvEpMacTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagTagPlan, tagTagState []TagTagFvEpMacTagResourceModel) []map[string]interface{} { +func getFvEpMacTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagTagFvEpMacTagPlan, tagTagFvEpMacTagState []TagTagFvEpMacTagResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagTag.Key.ValueString() + for _, tagTagFvEpMacTag := range tagTagFvEpMacTagPlan { + if !tagTagFvEpMacTag.Key.IsNull() && !tagTagFvEpMacTag.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagFvEpMacTag.Key.ValueString() } - if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagTag.Value.ValueString() + if !tagTagFvEpMacTag.Value.IsNull() && !tagTagFvEpMacTag.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagFvEpMacTag.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagFvEpMacTag.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagFvEpMacTagState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { 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 742634ae7..205f480be 100644 --- a/internal/provider/resource_aci_external_management_network_instance_profile.go +++ b/internal/provider/resource_aci_external_management_network_instance_profile.go @@ -60,6 +60,8 @@ type MgmtRsOoBConsMgmtInstPResourceModel struct { Annotation types.String `tfsdk:"annotation"` Prio types.String `tfsdk:"priority"` TnVzOOBBrCPName types.String `tfsdk:"out_of_band_contract_name"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` } func MgmtRsOoBConsMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { @@ -67,6 +69,8 @@ func MgmtRsOoBConsMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { "annotation": types.StringType, "priority": types.StringType, "out_of_band_contract_name": types.StringType, + "annotations": types.SetType{ElemType: types.StringType}, + "tags": types.SetType{ElemType: types.StringType}, } } @@ -74,6 +78,40 @@ func MgmtRsOoBConsMgmtInstPResourceModelElementType() attr.TypeWithAttributeType return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, MgmtRsOoBConsMgmtInstPResourceModelAttributeTypes()) } +// TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationMgmtRsOoBConsMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationMgmtRsOoBConsMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtRsOoBConsMgmtInstPResourceModelAttributeTypes()) +} + +// TagTagMgmtRsOoBConsMgmtInstPResourceModel describes the resource data model for the children without relation ships. +type TagTagMgmtRsOoBConsMgmtInstPResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagMgmtRsOoBConsMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagMgmtRsOoBConsMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtRsOoBConsMgmtInstPResourceModelAttributeTypes()) +} + // TagAnnotationMgmtInstPResourceModel describes the resource data model for the children without relation ships. type TagAnnotationMgmtInstPResourceModel struct { Key types.String `tfsdk:"key"` @@ -219,6 +257,62 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque }, MarkdownDescription: `The name of the Out Of Band Contract object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, }, }, @@ -457,7 +551,7 @@ func (r *MgmtInstPResource) ImportState(ctx context.Context, req resource.Import } func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *MgmtInstPResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtInstP,mgmtRsOoBCons,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtInstP,mgmtRsOoBCons,tagAnnotation,tagTag,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -503,6 +597,10 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, } MgmtRsOoBConsMgmtInstP := MgmtRsOoBConsMgmtInstPResourceModel{} MgmtRsOoBConsMgmtInstPList := make([]MgmtRsOoBConsMgmtInstPResourceModel, 0) + TagAnnotationMgmtRsOoBConsMgmtInstP := TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel{} + TagAnnotationMgmtRsOoBConsMgmtInstPList := make([]TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel, 0) + TagTagMgmtRsOoBConsMgmtInstP := TagTagMgmtRsOoBConsMgmtInstPResourceModel{} + TagTagMgmtRsOoBConsMgmtInstPList := make([]TagTagMgmtRsOoBConsMgmtInstPResourceModel, 0) TagAnnotationMgmtInstP := TagAnnotationMgmtInstPResourceModel{} TagAnnotationMgmtInstPList := make([]TagAnnotationMgmtInstPResourceModel, 0) TagTagMgmtInstP := TagTagMgmtInstPResourceModel{} @@ -526,6 +624,41 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, } } + childrenOfMgmtRsOoBConsMgmtInstP, childrenOfMgmtRsOoBConsMgmtInstPExist := childClassDetails.(map[string]interface{})["children"] + if childrenOfMgmtRsOoBConsMgmtInstPExist { + for _, childMgmtRsOoBConsMgmtInstP := range childrenOfMgmtRsOoBConsMgmtInstP.([]interface{}) { + for childClassNameMgmtRsOoBConsMgmtInstP, childClassDetailsMgmtRsOoBConsMgmtInstP := range childMgmtRsOoBConsMgmtInstP.(map[string]interface{}) { + if childClassNameMgmtRsOoBConsMgmtInstP == "tagAnnotation" { + tagAnnotationchildAttributeValue := childClassDetailsMgmtRsOoBConsMgmtInstP.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { + if childAttributeName == "key" { + TagAnnotationMgmtRsOoBConsMgmtInstP.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationMgmtRsOoBConsMgmtInstP.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagAnnotationMgmtRsOoBConsMgmtInstPList = append(TagAnnotationMgmtRsOoBConsMgmtInstPList, TagAnnotationMgmtRsOoBConsMgmtInstP) + } + if childClassNameMgmtRsOoBConsMgmtInstP == "tagTag" { + tagTagchildAttributeValue := childClassDetailsMgmtRsOoBConsMgmtInstP.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { + if childAttributeName == "key" { + TagTagMgmtRsOoBConsMgmtInstP.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagMgmtRsOoBConsMgmtInstP.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagTagMgmtRsOoBConsMgmtInstPList = append(TagTagMgmtRsOoBConsMgmtInstPList, TagTagMgmtRsOoBConsMgmtInstP) + } + } + } + } + TagAnnotationSet, _ := types.SetValueFrom(ctx, TagAnnotationMgmtRsOoBConsMgmtInstPResourceModelElementType(), TagAnnotationMgmtRsOoBConsMgmtInstPList) + MgmtRsOoBConsMgmtInstP.TagAnnotation = TagAnnotationSet + TagTagSet, _ := types.SetValueFrom(ctx, TagTagMgmtRsOoBConsMgmtInstPResourceModelElementType(), TagTagMgmtRsOoBConsMgmtInstPList) + MgmtRsOoBConsMgmtInstP.TagTag = TagTagSet MgmtRsOoBConsMgmtInstPList = append(MgmtRsOoBConsMgmtInstPList, MgmtRsOoBConsMgmtInstP) } if childClassName == "tagAnnotation" { @@ -587,29 +720,75 @@ func setMgmtInstPId(ctx context.Context, data *MgmtInstPResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", strings.Split([]string{"uni/tn-mgmt/extmgmt-default/instp-{name}"}[0], "/")[0], rn)) } -func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, mgmtRsOoBConsPlan, mgmtRsOoBConsState []MgmtRsOoBConsMgmtInstPResourceModel) []map[string]interface{} { +func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, mgmtRsOoBConsMgmtInstPPlan, mgmtRsOoBConsMgmtInstPState []MgmtRsOoBConsMgmtInstPResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} + tagAnnotationMgmtRsOoBConsMgmtInstPChildMap := NewAciObject() + tagTagMgmtRsOoBConsMgmtInstPChildMap := NewAciObject() + MgmtRsOoBConsMgmtInstPChildren := make([]map[string]interface{}, 0) if !data.MgmtRsOoBCons.IsNull() && !data.MgmtRsOoBCons.IsUnknown() { mgmtRsOoBConsIdentifiers := []MgmtRsOoBConsIdentifier{} - for _, mgmtRsOoBCons := range mgmtRsOoBConsPlan { - if !mgmtRsOoBCons.Annotation.IsNull() && !mgmtRsOoBCons.Annotation.IsUnknown() { - childMap.Attributes["annotation"] = mgmtRsOoBCons.Annotation.ValueString() + for _, mgmtRsOoBConsMgmtInstP := range mgmtRsOoBConsMgmtInstPPlan { + if !mgmtRsOoBConsMgmtInstP.Annotation.IsNull() && !mgmtRsOoBConsMgmtInstP.Annotation.IsUnknown() { + childMap.Attributes["annotation"] = mgmtRsOoBConsMgmtInstP.Annotation.ValueString() } else { childMap.Attributes["annotation"] = globalAnnotation } - if !mgmtRsOoBCons.Prio.IsNull() && !mgmtRsOoBCons.Prio.IsUnknown() { - childMap.Attributes["prio"] = mgmtRsOoBCons.Prio.ValueString() + if !mgmtRsOoBConsMgmtInstP.Prio.IsNull() && !mgmtRsOoBConsMgmtInstP.Prio.IsUnknown() { + childMap.Attributes["prio"] = mgmtRsOoBConsMgmtInstP.Prio.ValueString() + } + if !mgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName.IsNull() && !mgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName.IsUnknown() { + childMap.Attributes["tnVzOOBBrCPName"] = mgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName.ValueString() } - if !mgmtRsOoBCons.TnVzOOBBrCPName.IsNull() && !mgmtRsOoBCons.TnVzOOBBrCPName.IsUnknown() { - childMap.Attributes["tnVzOOBBrCPName"] = mgmtRsOoBCons.TnVzOOBBrCPName.ValueString() + var tagAnnotationMgmtRsOoBConsMgmtInstPPlan, tagAnnotationMgmtRsOoBConsMgmtInstPState []TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel + mgmtRsOoBConsMgmtInstP.TagAnnotation.ElementsAs(ctx, &tagAnnotationMgmtRsOoBConsMgmtInstPPlan, false) + for _, mgmtRsOoBConstagAnnotationState := range mgmtRsOoBConsMgmtInstPState { + mgmtRsOoBConstagAnnotationState.TagAnnotation.ElementsAs(ctx, &tagAnnotationMgmtRsOoBConsMgmtInstPState, false) + if len(tagAnnotationMgmtRsOoBConsMgmtInstPPlan) == 0 && len(tagAnnotationMgmtRsOoBConsMgmtInstPState) == 1 { + tagAnnotationMgmtRsOoBConsMgmtInstPChildMap := NewAciObject() + tagAnnotationMgmtRsOoBConsMgmtInstPChildMap.Attributes["status"] = "deleted" + MgmtRsOoBConsMgmtInstPChildren = append(MgmtRsOoBConsMgmtInstPChildren, map[string]interface{}{"tagAnnotation": tagAnnotationMgmtRsOoBConsMgmtInstPChildMap}) + } + } + if !mgmtRsOoBConsMgmtInstP.TagAnnotation.IsNull() && !mgmtRsOoBConsMgmtInstP.TagAnnotation.IsUnknown() { + for _, tagAnnotationMgmtRsOoBConsMgmtInstP := range tagAnnotationMgmtRsOoBConsMgmtInstPPlan { + if !tagAnnotationMgmtRsOoBConsMgmtInstP.Key.IsNull() && !tagAnnotationMgmtRsOoBConsMgmtInstP.Key.IsUnknown() { + tagAnnotationMgmtRsOoBConsMgmtInstPChildMap.Attributes["key"] = tagAnnotationMgmtRsOoBConsMgmtInstP.Key.ValueString() + } + if !tagAnnotationMgmtRsOoBConsMgmtInstP.Value.IsNull() && !tagAnnotationMgmtRsOoBConsMgmtInstP.Value.IsUnknown() { + tagAnnotationMgmtRsOoBConsMgmtInstPChildMap.Attributes["value"] = tagAnnotationMgmtRsOoBConsMgmtInstP.Value.ValueString() + } + MgmtRsOoBConsMgmtInstPChildren = append(MgmtRsOoBConsMgmtInstPChildren, map[string]interface{}{"tagAnnotation": tagAnnotationMgmtRsOoBConsMgmtInstPChildMap}) + } + } + var tagTagMgmtRsOoBConsMgmtInstPPlan, tagTagMgmtRsOoBConsMgmtInstPState []TagTagMgmtRsOoBConsMgmtInstPResourceModel + mgmtRsOoBConsMgmtInstP.TagTag.ElementsAs(ctx, &tagTagMgmtRsOoBConsMgmtInstPPlan, false) + for _, mgmtRsOoBConstagTagState := range mgmtRsOoBConsMgmtInstPState { + mgmtRsOoBConstagTagState.TagTag.ElementsAs(ctx, &tagTagMgmtRsOoBConsMgmtInstPState, false) + if len(tagTagMgmtRsOoBConsMgmtInstPPlan) == 0 && len(tagTagMgmtRsOoBConsMgmtInstPState) == 1 { + tagTagMgmtRsOoBConsMgmtInstPChildMap := NewAciObject() + tagTagMgmtRsOoBConsMgmtInstPChildMap.Attributes["status"] = "deleted" + MgmtRsOoBConsMgmtInstPChildren = append(MgmtRsOoBConsMgmtInstPChildren, map[string]interface{}{"tagTag": tagTagMgmtRsOoBConsMgmtInstPChildMap}) + } + } + if !mgmtRsOoBConsMgmtInstP.TagTag.IsNull() && !mgmtRsOoBConsMgmtInstP.TagTag.IsUnknown() { + for _, tagTagMgmtRsOoBConsMgmtInstP := range tagTagMgmtRsOoBConsMgmtInstPPlan { + if !tagTagMgmtRsOoBConsMgmtInstP.Key.IsNull() && !tagTagMgmtRsOoBConsMgmtInstP.Key.IsUnknown() { + tagTagMgmtRsOoBConsMgmtInstPChildMap.Attributes["key"] = tagTagMgmtRsOoBConsMgmtInstP.Key.ValueString() + } + if !tagTagMgmtRsOoBConsMgmtInstP.Value.IsNull() && !tagTagMgmtRsOoBConsMgmtInstP.Value.IsUnknown() { + tagTagMgmtRsOoBConsMgmtInstPChildMap.Attributes["value"] = tagTagMgmtRsOoBConsMgmtInstP.Value.ValueString() + } + MgmtRsOoBConsMgmtInstPChildren = append(MgmtRsOoBConsMgmtInstPChildren, map[string]interface{}{"tagTag": tagTagMgmtRsOoBConsMgmtInstPChildMap}) + } } + childMap.Children = MgmtRsOoBConsMgmtInstPChildren childPayloads = append(childPayloads, map[string]interface{}{"mgmtRsOoBCons": childMap}) mgmtRsOoBConsIdentifier := MgmtRsOoBConsIdentifier{} - mgmtRsOoBConsIdentifier.TnVzOOBBrCPName = mgmtRsOoBCons.TnVzOOBBrCPName + mgmtRsOoBConsIdentifier.TnVzOOBBrCPName = mgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName mgmtRsOoBConsIdentifiers = append(mgmtRsOoBConsIdentifiers, mgmtRsOoBConsIdentifier) } - for _, mgmtRsOoBCons := range mgmtRsOoBConsState { + for _, mgmtRsOoBCons := range mgmtRsOoBConsMgmtInstPState { delete := true for _, mgmtRsOoBConsIdentifier := range mgmtRsOoBConsIdentifiers { if mgmtRsOoBConsIdentifier.TnVzOOBBrCPName == mgmtRsOoBCons.TnVzOOBBrCPName { @@ -631,24 +810,24 @@ func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Dia return childPayloads } -func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtInstPResourceModel) []map[string]interface{} { +func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagAnnotationMgmtInstPPlan, tagAnnotationMgmtInstPState []TagAnnotationMgmtInstPResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationMgmtInstP := range tagAnnotationMgmtInstPPlan { + if !tagAnnotationMgmtInstP.Key.IsNull() && !tagAnnotationMgmtInstP.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationMgmtInstP.Key.ValueString() } - if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationMgmtInstP.Value.IsNull() && !tagAnnotationMgmtInstP.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationMgmtInstP.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationMgmtInstP.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationMgmtInstPState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -670,24 +849,24 @@ func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia return childPayloads } -func getMgmtInstPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagTagPlan, tagTagState []TagTagMgmtInstPResourceModel) []map[string]interface{} { +func getMgmtInstPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagTagMgmtInstPPlan, tagTagMgmtInstPState []TagTagMgmtInstPResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagTag.Key.ValueString() + for _, tagTagMgmtInstP := range tagTagMgmtInstPPlan { + if !tagTagMgmtInstP.Key.IsNull() && !tagTagMgmtInstP.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagMgmtInstP.Key.ValueString() } - if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagTag.Value.ValueString() + if !tagTagMgmtInstP.Value.IsNull() && !tagTagMgmtInstP.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagMgmtInstP.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagMgmtInstP.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagMgmtInstPState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { diff --git a/internal/provider/resource_aci_external_management_network_subnet.go b/internal/provider/resource_aci_external_management_network_subnet.go index b37d30cb0..c09a9aaae 100644 --- a/internal/provider/resource_aci_external_management_network_subnet.go +++ b/internal/provider/resource_aci_external_management_network_subnet.go @@ -522,24 +522,24 @@ func setMgmtSubnetId(ctx context.Context, data *MgmtSubnetResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getMgmtSubnetTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtSubnetResourceModel) []map[string]interface{} { +func getMgmtSubnetTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagAnnotationMgmtSubnetPlan, tagAnnotationMgmtSubnetState []TagAnnotationMgmtSubnetResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationMgmtSubnet := range tagAnnotationMgmtSubnetPlan { + if !tagAnnotationMgmtSubnet.Key.IsNull() && !tagAnnotationMgmtSubnet.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationMgmtSubnet.Key.ValueString() } - if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationMgmtSubnet.Value.IsNull() && !tagAnnotationMgmtSubnet.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationMgmtSubnet.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationMgmtSubnet.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationMgmtSubnetState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -561,24 +561,24 @@ func getMgmtSubnetTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di return childPayloads } -func getMgmtSubnetTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagTagPlan, tagTagState []TagTagMgmtSubnetResourceModel) []map[string]interface{} { +func getMgmtSubnetTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagTagMgmtSubnetPlan, tagTagMgmtSubnetState []TagTagMgmtSubnetResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagTag.Key.ValueString() + for _, tagTagMgmtSubnet := range tagTagMgmtSubnetPlan { + if !tagTagMgmtSubnet.Key.IsNull() && !tagTagMgmtSubnet.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagMgmtSubnet.Key.ValueString() } - if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagTag.Value.ValueString() + if !tagTagMgmtSubnet.Value.IsNull() && !tagTagMgmtSubnet.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagMgmtSubnet.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagMgmtSubnet.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagMgmtSubnetState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { diff --git a/internal/provider/resource_aci_l3out_consumer_label.go b/internal/provider/resource_aci_l3out_consumer_label.go index ed2fe3477..5ec47f1fa 100644 --- a/internal/provider/resource_aci_l3out_consumer_label.go +++ b/internal/provider/resource_aci_l3out_consumer_label.go @@ -578,24 +578,24 @@ func setL3extConsLblId(ctx context.Context, data *L3extConsLblResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getL3extConsLblTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extConsLblResourceModel) []map[string]interface{} { +func getL3extConsLblTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagAnnotationL3extConsLblPlan, tagAnnotationL3extConsLblState []TagAnnotationL3extConsLblResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationL3extConsLbl := range tagAnnotationL3extConsLblPlan { + if !tagAnnotationL3extConsLbl.Key.IsNull() && !tagAnnotationL3extConsLbl.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationL3extConsLbl.Key.ValueString() } - if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationL3extConsLbl.Value.IsNull() && !tagAnnotationL3extConsLbl.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationL3extConsLbl.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationL3extConsLbl.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationL3extConsLblState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -617,24 +617,24 @@ func getL3extConsLblTagAnnotationChildPayloads(ctx context.Context, diags *diag. return childPayloads } -func getL3extConsLblTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagTagPlan, tagTagState []TagTagL3extConsLblResourceModel) []map[string]interface{} { +func getL3extConsLblTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagTagL3extConsLblPlan, tagTagL3extConsLblState []TagTagL3extConsLblResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagTag.Key.ValueString() + for _, tagTagL3extConsLbl := range tagTagL3extConsLblPlan { + if !tagTagL3extConsLbl.Key.IsNull() && !tagTagL3extConsLbl.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagL3extConsLbl.Key.ValueString() } - if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagTag.Value.ValueString() + if !tagTagL3extConsLbl.Value.IsNull() && !tagTagL3extConsLbl.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagL3extConsLbl.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagL3extConsLbl.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagL3extConsLblState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { diff --git a/internal/provider/resource_aci_l3out_redistribute_policy.go b/internal/provider/resource_aci_l3out_redistribute_policy.go index 8a229a697..ef24891e9 100644 --- a/internal/provider/resource_aci_l3out_redistribute_policy.go +++ b/internal/provider/resource_aci_l3out_redistribute_policy.go @@ -496,24 +496,24 @@ func setL3extRsRedistributePolId(ctx context.Context, data *L3extRsRedistributeP data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getL3extRsRedistributePolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsRedistributePolResourceModel) []map[string]interface{} { +func getL3extRsRedistributePolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagAnnotationL3extRsRedistributePolPlan, tagAnnotationL3extRsRedistributePolState []TagAnnotationL3extRsRedistributePolResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationL3extRsRedistributePol := range tagAnnotationL3extRsRedistributePolPlan { + if !tagAnnotationL3extRsRedistributePol.Key.IsNull() && !tagAnnotationL3extRsRedistributePol.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationL3extRsRedistributePol.Key.ValueString() } - if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationL3extRsRedistributePol.Value.IsNull() && !tagAnnotationL3extRsRedistributePol.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationL3extRsRedistributePol.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationL3extRsRedistributePol.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationL3extRsRedistributePolState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -535,24 +535,24 @@ func getL3extRsRedistributePolTagAnnotationChildPayloads(ctx context.Context, di return childPayloads } -func getL3extRsRedistributePolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagTagPlan, tagTagState []TagTagL3extRsRedistributePolResourceModel) []map[string]interface{} { +func getL3extRsRedistributePolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagTagL3extRsRedistributePolPlan, tagTagL3extRsRedistributePolState []TagTagL3extRsRedistributePolResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagTag.Key.ValueString() + for _, tagTagL3extRsRedistributePol := range tagTagL3extRsRedistributePolPlan { + if !tagTagL3extRsRedistributePol.Key.IsNull() && !tagTagL3extRsRedistributePol.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagL3extRsRedistributePol.Key.ValueString() } - if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagTag.Value.ValueString() + if !tagTagL3extRsRedistributePol.Value.IsNull() && !tagTagL3extRsRedistributePol.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagL3extRsRedistributePol.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagL3extRsRedistributePol.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagL3extRsRedistributePolState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { diff --git a/internal/provider/resource_aci_out_of_band_contract.go b/internal/provider/resource_aci_out_of_band_contract.go index 6b786dfa7..5639d94fd 100644 --- a/internal/provider/resource_aci_out_of_band_contract.go +++ b/internal/provider/resource_aci_out_of_band_contract.go @@ -590,24 +590,24 @@ func setVzOOBBrCPId(ctx context.Context, data *VzOOBBrCPResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", strings.Split([]string{"uni/tn-mgmt/oobbrc-{name}"}[0], "/")[0], rn)) } -func getVzOOBBrCPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationVzOOBBrCPResourceModel) []map[string]interface{} { +func getVzOOBBrCPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagAnnotationVzOOBBrCPPlan, tagAnnotationVzOOBBrCPState []TagAnnotationVzOOBBrCPResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationVzOOBBrCP := range tagAnnotationVzOOBBrCPPlan { + if !tagAnnotationVzOOBBrCP.Key.IsNull() && !tagAnnotationVzOOBBrCP.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationVzOOBBrCP.Key.ValueString() } - if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationVzOOBBrCP.Value.IsNull() && !tagAnnotationVzOOBBrCP.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationVzOOBBrCP.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationVzOOBBrCP.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationVzOOBBrCPState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -629,24 +629,24 @@ func getVzOOBBrCPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Dia return childPayloads } -func getVzOOBBrCPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagTagPlan, tagTagState []TagTagVzOOBBrCPResourceModel) []map[string]interface{} { +func getVzOOBBrCPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagTagVzOOBBrCPPlan, tagTagVzOOBBrCPState []TagTagVzOOBBrCPResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagTag.Key.ValueString() + for _, tagTagVzOOBBrCP := range tagTagVzOOBBrCPPlan { + if !tagTagVzOOBBrCP.Key.IsNull() && !tagTagVzOOBBrCP.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagVzOOBBrCP.Key.ValueString() } - if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagTag.Value.ValueString() + if !tagTagVzOOBBrCP.Value.IsNull() && !tagTagVzOOBBrCP.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagVzOOBBrCP.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagVzOOBBrCP.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagVzOOBBrCPState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { diff --git a/internal/provider/resource_aci_pim_route_map_entry.go b/internal/provider/resource_aci_pim_route_map_entry.go index bbe6c25f2..8870151d0 100644 --- a/internal/provider/resource_aci_pim_route_map_entry.go +++ b/internal/provider/resource_aci_pim_route_map_entry.go @@ -591,24 +591,24 @@ func setPimRouteMapEntryId(ctx context.Context, data *PimRouteMapEntryResourceMo data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getPimRouteMapEntryTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapEntryResourceModel) []map[string]interface{} { +func getPimRouteMapEntryTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagAnnotationPimRouteMapEntryPlan, tagAnnotationPimRouteMapEntryState []TagAnnotationPimRouteMapEntryResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationPimRouteMapEntry := range tagAnnotationPimRouteMapEntryPlan { + if !tagAnnotationPimRouteMapEntry.Key.IsNull() && !tagAnnotationPimRouteMapEntry.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationPimRouteMapEntry.Key.ValueString() } - if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationPimRouteMapEntry.Value.IsNull() && !tagAnnotationPimRouteMapEntry.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationPimRouteMapEntry.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationPimRouteMapEntry.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationPimRouteMapEntryState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -630,24 +630,24 @@ func getPimRouteMapEntryTagAnnotationChildPayloads(ctx context.Context, diags *d return childPayloads } -func getPimRouteMapEntryTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagTagPlan, tagTagState []TagTagPimRouteMapEntryResourceModel) []map[string]interface{} { +func getPimRouteMapEntryTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagTagPimRouteMapEntryPlan, tagTagPimRouteMapEntryState []TagTagPimRouteMapEntryResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagTag.Key.ValueString() + for _, tagTagPimRouteMapEntry := range tagTagPimRouteMapEntryPlan { + if !tagTagPimRouteMapEntry.Key.IsNull() && !tagTagPimRouteMapEntry.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagPimRouteMapEntry.Key.ValueString() } - if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagTag.Value.ValueString() + if !tagTagPimRouteMapEntry.Value.IsNull() && !tagTagPimRouteMapEntry.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagPimRouteMapEntry.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagPimRouteMapEntry.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagPimRouteMapEntryState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { diff --git a/internal/provider/resource_aci_pim_route_map_policy.go b/internal/provider/resource_aci_pim_route_map_policy.go index 47fd6bf0c..b925b928e 100644 --- a/internal/provider/resource_aci_pim_route_map_policy.go +++ b/internal/provider/resource_aci_pim_route_map_policy.go @@ -538,24 +538,24 @@ func setPimRouteMapPolId(ctx context.Context, data *PimRouteMapPolResourceModel) data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getPimRouteMapPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapPolResourceModel) []map[string]interface{} { +func getPimRouteMapPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagAnnotationPimRouteMapPolPlan, tagAnnotationPimRouteMapPolState []TagAnnotationPimRouteMapPolResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationPimRouteMapPol := range tagAnnotationPimRouteMapPolPlan { + if !tagAnnotationPimRouteMapPol.Key.IsNull() && !tagAnnotationPimRouteMapPol.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationPimRouteMapPol.Key.ValueString() } - if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationPimRouteMapPol.Value.IsNull() && !tagAnnotationPimRouteMapPol.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationPimRouteMapPol.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationPimRouteMapPol.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationPimRouteMapPolState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -577,24 +577,24 @@ func getPimRouteMapPolTagAnnotationChildPayloads(ctx context.Context, diags *dia return childPayloads } -func getPimRouteMapPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagTagPlan, tagTagState []TagTagPimRouteMapPolResourceModel) []map[string]interface{} { +func getPimRouteMapPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagTagPimRouteMapPolPlan, tagTagPimRouteMapPolState []TagTagPimRouteMapPolResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagTag.Key.ValueString() + for _, tagTagPimRouteMapPol := range tagTagPimRouteMapPolPlan { + if !tagTagPimRouteMapPol.Key.IsNull() && !tagTagPimRouteMapPol.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagPimRouteMapPol.Key.ValueString() } - if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagTag.Value.ValueString() + if !tagTagPimRouteMapPol.Value.IsNull() && !tagTagPimRouteMapPol.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagPimRouteMapPol.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagPimRouteMapPol.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagPimRouteMapPolState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { diff --git a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go index a5477a636..29d0237b8 100644 --- a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go +++ b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go @@ -495,24 +495,24 @@ func setMgmtRsOoBConsId(ctx context.Context, data *MgmtRsOoBConsResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getMgmtRsOoBConsTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtRsOoBConsResourceModel) []map[string]interface{} { +func getMgmtRsOoBConsTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagAnnotationMgmtRsOoBConsPlan, tagAnnotationMgmtRsOoBConsState []TagAnnotationMgmtRsOoBConsResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - if !tagAnnotation.Key.IsNull() && !tagAnnotation.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationMgmtRsOoBCons := range tagAnnotationMgmtRsOoBConsPlan { + if !tagAnnotationMgmtRsOoBCons.Key.IsNull() && !tagAnnotationMgmtRsOoBCons.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationMgmtRsOoBCons.Key.ValueString() } - if !tagAnnotation.Value.IsNull() && !tagAnnotation.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationMgmtRsOoBCons.Value.IsNull() && !tagAnnotationMgmtRsOoBCons.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationMgmtRsOoBCons.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationMgmtRsOoBCons.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationMgmtRsOoBConsState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -534,24 +534,24 @@ func getMgmtRsOoBConsTagAnnotationChildPayloads(ctx context.Context, diags *diag return childPayloads } -func getMgmtRsOoBConsTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagTagPlan, tagTagState []TagTagMgmtRsOoBConsResourceModel) []map[string]interface{} { +func getMgmtRsOoBConsTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagTagMgmtRsOoBConsPlan, tagTagMgmtRsOoBConsState []TagTagMgmtRsOoBConsResourceModel) []map[string]interface{} { childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - if !tagTag.Key.IsNull() && !tagTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagTag.Key.ValueString() + for _, tagTagMgmtRsOoBCons := range tagTagMgmtRsOoBConsPlan { + if !tagTagMgmtRsOoBCons.Key.IsNull() && !tagTagMgmtRsOoBCons.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagMgmtRsOoBCons.Key.ValueString() } - if !tagTag.Value.IsNull() && !tagTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagTag.Value.ValueString() + if !tagTagMgmtRsOoBCons.Value.IsNull() && !tagTagMgmtRsOoBCons.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagMgmtRsOoBCons.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagMgmtRsOoBCons.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagMgmtRsOoBConsState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { diff --git a/internal/provider/resource_aci_relation_to_fallback_route_group.go b/internal/provider/resource_aci_relation_to_fallback_route_group.go index 008b9e309..0809fa7d3 100644 --- a/internal/provider/resource_aci_relation_to_fallback_route_group.go +++ b/internal/provider/resource_aci_relation_to_fallback_route_group.go @@ -13,6 +13,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -55,12 +56,34 @@ type TagAnnotationL3extRsOutToFBRGroupResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationL3extRsOutToFBRGroupResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationL3extRsOutToFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationL3extRsOutToFBRGroupResourceModelAttributeTypes()) +} + // TagTagL3extRsOutToFBRGroupResourceModel describes the resource data model for the children without relation ships. type TagTagL3extRsOutToFBRGroupResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagL3extRsOutToFBRGroupResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagL3extRsOutToFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagL3extRsOutToFBRGroupResourceModelAttributeTypes()) +} + type L3extRsOutToFBRGroupIdentifier struct { TDn types.String } @@ -98,6 +121,7 @@ func (r *L3extRsOutToFBRGroupResource) Schema(ctx context.Context, req resource. Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the Relation To Fallback Route Group object.`, @@ -106,6 +130,7 @@ func (r *L3extRsOutToFBRGroupResource) Schema(ctx context.Context, req resource. Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The distinguished name of the VRF Fallback Route Group object.`, @@ -123,6 +148,7 @@ func (r *L3extRsOutToFBRGroupResource) Schema(ctx context.Context, req resource. Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -130,6 +156,7 @@ func (r *L3extRsOutToFBRGroupResource) Schema(ctx context.Context, req resource. Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -149,6 +176,7 @@ func (r *L3extRsOutToFBRGroupResource) Schema(ctx context.Context, req resource. Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -156,6 +184,7 @@ func (r *L3extRsOutToFBRGroupResource) Schema(ctx context.Context, req resource. Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -335,7 +364,7 @@ func (r *L3extRsOutToFBRGroupResource) ImportState(ctx context.Context, req reso } func getAndSetL3extRsOutToFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *L3extRsOutToFBRGroupResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "l3extRsOutToFBRGroup,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "l3extRsOutToFBRGroup,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -356,7 +385,15 @@ func getAndSetL3extRsOutToFBRGroupAttributes(ctx context.Context, diags *diag.Di data.TDn = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.TDn.IsUnknown() { + data.TDn = types.StringNull() + } + TagAnnotationL3extRsOutToFBRGroup := TagAnnotationL3extRsOutToFBRGroupResourceModel{} TagAnnotationL3extRsOutToFBRGroupList := make([]TagAnnotationL3extRsOutToFBRGroupResourceModel, 0) + TagTagL3extRsOutToFBRGroup := TagTagL3extRsOutToFBRGroupResourceModel{} TagTagL3extRsOutToFBRGroupList := make([]TagTagL3extRsOutToFBRGroupResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -365,7 +402,6 @@ func getAndSetL3extRsOutToFBRGroupAttributes(ctx context.Context, diags *diag.Di for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "tagAnnotation" { - TagAnnotationL3extRsOutToFBRGroup := TagAnnotationL3extRsOutToFBRGroupResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationL3extRsOutToFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -373,11 +409,11 @@ func getAndSetL3extRsOutToFBRGroupAttributes(ctx context.Context, diags *diag.Di if childAttributeName == "value" { TagAnnotationL3extRsOutToFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) } + } TagAnnotationL3extRsOutToFBRGroupList = append(TagAnnotationL3extRsOutToFBRGroupList, TagAnnotationL3extRsOutToFBRGroup) } if childClassName == "tagTag" { - TagTagL3extRsOutToFBRGroup := TagTagL3extRsOutToFBRGroupResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagL3extRsOutToFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -385,6 +421,7 @@ func getAndSetL3extRsOutToFBRGroupAttributes(ctx context.Context, diags *diag.Di if childAttributeName == "value" { TagTagL3extRsOutToFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) } + } TagTagL3extRsOutToFBRGroupList = append(TagTagL3extRsOutToFBRGroupList, TagTagL3extRsOutToFBRGroup) } @@ -437,25 +474,24 @@ func setL3extRsOutToFBRGroupId(ctx context.Context, data *L3extRsOutToFBRGroupRe data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getL3extRsOutToFBRGroupTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsOutToFBRGroupResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsOutToFBRGroupResourceModel) []map[string]interface{} { - +func getL3extRsOutToFBRGroupTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsOutToFBRGroupResourceModel, tagAnnotationL3extRsOutToFBRGroupPlan, tagAnnotationL3extRsOutToFBRGroupState []TagAnnotationL3extRsOutToFBRGroupResourceModel) []map[string]interface{} { + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationL3extRsOutToFBRGroup := range tagAnnotationL3extRsOutToFBRGroupPlan { + if !tagAnnotationL3extRsOutToFBRGroup.Key.IsNull() && !tagAnnotationL3extRsOutToFBRGroup.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationL3extRsOutToFBRGroup.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationL3extRsOutToFBRGroup.Value.IsNull() && !tagAnnotationL3extRsOutToFBRGroup.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationL3extRsOutToFBRGroup.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationL3extRsOutToFBRGroup.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationL3extRsOutToFBRGroupState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -464,10 +500,10 @@ func getL3extRsOutToFBRGroupTagAnnotationChildPayloads(ctx context.Context, diag } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -476,25 +512,25 @@ func getL3extRsOutToFBRGroupTagAnnotationChildPayloads(ctx context.Context, diag return childPayloads } -func getL3extRsOutToFBRGroupTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsOutToFBRGroupResourceModel, tagTagPlan, tagTagState []TagTagL3extRsOutToFBRGroupResourceModel) []map[string]interface{} { +func getL3extRsOutToFBRGroupTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsOutToFBRGroupResourceModel, tagTagL3extRsOutToFBRGroupPlan, tagTagL3extRsOutToFBRGroupState []TagTagL3extRsOutToFBRGroupResourceModel) []map[string]interface{} { + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + for _, tagTagL3extRsOutToFBRGroup := range tagTagL3extRsOutToFBRGroupPlan { + if !tagTagL3extRsOutToFBRGroup.Key.IsNull() && !tagTagL3extRsOutToFBRGroup.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagL3extRsOutToFBRGroup.Key.ValueString() } - if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + if !tagTagL3extRsOutToFBRGroup.Value.IsNull() && !tagTagL3extRsOutToFBRGroup.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagL3extRsOutToFBRGroup.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagL3extRsOutToFBRGroup.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagL3extRsOutToFBRGroupState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { @@ -503,10 +539,10 @@ func getL3extRsOutToFBRGroupTagTagChildPayloads(ctx context.Context, diags *diag } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { diff --git a/internal/provider/resource_aci_vrf_fallback_route_group.go b/internal/provider/resource_aci_vrf_fallback_route_group.go index a1f9c231b..38bc77029 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group.go @@ -13,6 +13,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -54,11 +55,63 @@ type FvFBRGroupResourceModel struct { // FvFBRMemberFvFBRGroupResourceModel describes the resource data model for the children without relation ships. type FvFBRMemberFvFBRGroupResourceModel struct { - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - RnhAddr types.String `tfsdk:"fallback_member"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + RnhAddr types.String `tfsdk:"fallback_member"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` +} + +func FvFBRMemberFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "annotation": types.StringType, + "description": types.StringType, + "name": types.StringType, + "name_alias": types.StringType, + "fallback_member": types.StringType, + "annotations": types.SetType{ElemType: types.StringType}, + "tags": types.SetType{ElemType: types.StringType}, + } +} + +func FvFBRMemberFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, FvFBRMemberFvFBRGroupResourceModelAttributeTypes()) +} + +// TagAnnotationFvFBRMemberFvFBRGroupResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationFvFBRMemberFvFBRGroupResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationFvFBRMemberFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationFvFBRMemberFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvFBRMemberFvFBRGroupResourceModelAttributeTypes()) +} + +// TagTagFvFBRMemberFvFBRGroupResourceModel describes the resource data model for the children without relation ships. +type TagTagFvFBRMemberFvFBRGroupResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagFvFBRMemberFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagFvFBRMemberFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvFBRMemberFvFBRGroupResourceModelAttributeTypes()) } // TagAnnotationFvFBRGroupResourceModel describes the resource data model for the children without relation ships. @@ -67,12 +120,34 @@ type TagAnnotationFvFBRGroupResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvFBRGroupResourceModelAttributeTypes()) +} + // TagTagFvFBRGroupResourceModel describes the resource data model for the children without relation ships. type TagTagFvFBRGroupResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvFBRGroupResourceModelAttributeTypes()) +} + type FvFBRGroupIdentifier struct { Name types.String } @@ -110,6 +185,7 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the VRF Fallback Route Group object.`, @@ -119,6 +195,7 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The description of the VRF Fallback Route Group object.`, }, @@ -126,6 +203,7 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The name of the VRF Fallback Route Group object.`, @@ -135,6 +213,7 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the VRF Fallback Route Group object.`, }, @@ -152,6 +231,7 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The annotation of the VRF Fallback Route Group Member object.`, }, @@ -160,6 +240,7 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The description of the VRF Fallback Route Group Member object.`, }, @@ -168,6 +249,7 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name of the VRF Fallback Route Group Member object.`, }, @@ -176,6 +258,7 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the VRF Fallback Route Group Member object.`, }, @@ -183,9 +266,66 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The address of the VRF Fallback Route Group Member object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, }, }, @@ -202,6 +342,7 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -209,6 +350,7 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -228,6 +370,7 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -235,6 +378,7 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -420,7 +564,7 @@ func (r *FvFBRGroupResource) ImportState(ctx context.Context, req resource.Impor } func getAndSetFvFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *FvFBRGroupResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "fvFBRGroup,fvFBRMember,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "fvFBRGroup,fvFBRMember,tagAnnotation,tagTag,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -447,8 +591,27 @@ func getAndSetFvFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, data.NameAlias = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.Descr.IsUnknown() { + data.Descr = types.StringNull() + } + if data.Name.IsUnknown() { + data.Name = types.StringNull() + } + if data.NameAlias.IsUnknown() { + data.NameAlias = types.StringNull() + } + FvFBRMemberFvFBRGroup := FvFBRMemberFvFBRGroupResourceModel{} FvFBRMemberFvFBRGroupList := make([]FvFBRMemberFvFBRGroupResourceModel, 0) + TagAnnotationFvFBRMemberFvFBRGroup := TagAnnotationFvFBRMemberFvFBRGroupResourceModel{} + TagAnnotationFvFBRMemberFvFBRGroupList := make([]TagAnnotationFvFBRMemberFvFBRGroupResourceModel, 0) + TagTagFvFBRMemberFvFBRGroup := TagTagFvFBRMemberFvFBRGroupResourceModel{} + TagTagFvFBRMemberFvFBRGroupList := make([]TagTagFvFBRMemberFvFBRGroupResourceModel, 0) + TagAnnotationFvFBRGroup := TagAnnotationFvFBRGroupResourceModel{} TagAnnotationFvFBRGroupList := make([]TagAnnotationFvFBRGroupResourceModel, 0) + TagTagFvFBRGroup := TagTagFvFBRGroupResourceModel{} TagTagFvFBRGroupList := make([]TagTagFvFBRGroupResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -457,7 +620,6 @@ func getAndSetFvFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "fvFBRMember" { - FvFBRMemberFvFBRGroup := FvFBRMemberFvFBRGroupResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "annotation" { FvFBRMemberFvFBRGroup.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) @@ -474,11 +636,46 @@ func getAndSetFvFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, if childAttributeName == "rnhAddr" { FvFBRMemberFvFBRGroup.RnhAddr = basetypes.NewStringValue(childAttributeValue.(string)) } + } + childrenOfFvFBRMemberFvFBRGroup, childrenOfFvFBRMemberFvFBRGroupExist := childClassDetails.(map[string]interface{})["children"] + if childrenOfFvFBRMemberFvFBRGroupExist { + for _, childFvFBRMemberFvFBRGroup := range childrenOfFvFBRMemberFvFBRGroup.([]interface{}) { + for childClassNameFvFBRMemberFvFBRGroup, childClassDetailsFvFBRMemberFvFBRGroup := range childFvFBRMemberFvFBRGroup.(map[string]interface{}) { + if childClassNameFvFBRMemberFvFBRGroup == "tagAnnotation" { + tagAnnotationchildAttributeValue := childClassDetailsFvFBRMemberFvFBRGroup.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { + if childAttributeName == "key" { + TagAnnotationFvFBRMemberFvFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationFvFBRMemberFvFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagAnnotationFvFBRMemberFvFBRGroupList = append(TagAnnotationFvFBRMemberFvFBRGroupList, TagAnnotationFvFBRMemberFvFBRGroup) + } + if childClassNameFvFBRMemberFvFBRGroup == "tagTag" { + tagTagchildAttributeValue := childClassDetailsFvFBRMemberFvFBRGroup.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { + if childAttributeName == "key" { + TagTagFvFBRMemberFvFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagFvFBRMemberFvFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagTagFvFBRMemberFvFBRGroupList = append(TagTagFvFBRMemberFvFBRGroupList, TagTagFvFBRMemberFvFBRGroup) + } + } + } + } + TagAnnotationSet, _ := types.SetValueFrom(ctx, TagAnnotationFvFBRMemberFvFBRGroupResourceModelElementType(), TagAnnotationFvFBRMemberFvFBRGroupList) + FvFBRMemberFvFBRGroup.TagAnnotation = TagAnnotationSet + TagTagSet, _ := types.SetValueFrom(ctx, TagTagFvFBRMemberFvFBRGroupResourceModelElementType(), TagTagFvFBRMemberFvFBRGroupList) + FvFBRMemberFvFBRGroup.TagTag = TagTagSet FvFBRMemberFvFBRGroupList = append(FvFBRMemberFvFBRGroupList, FvFBRMemberFvFBRGroup) } if childClassName == "tagAnnotation" { - TagAnnotationFvFBRGroup := TagAnnotationFvFBRGroupResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationFvFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -486,11 +683,11 @@ func getAndSetFvFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, if childAttributeName == "value" { TagAnnotationFvFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) } + } TagAnnotationFvFBRGroupList = append(TagAnnotationFvFBRGroupList, TagAnnotationFvFBRGroup) } if childClassName == "tagTag" { - TagTagFvFBRGroup := TagTagFvFBRGroupResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagFvFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -498,6 +695,7 @@ func getAndSetFvFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, if childAttributeName == "value" { TagTagFvFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) } + } TagTagFvFBRGroupList = append(TagTagFvFBRGroupList, TagTagFvFBRGroup) } @@ -552,36 +750,81 @@ func setFvFBRGroupId(ctx context.Context, data *FvFBRGroupResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getFvFBRGroupFvFBRMemberChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, fvFBRMemberPlan, fvFBRMemberState []FvFBRMemberFvFBRGroupResourceModel) []map[string]interface{} { - +func getFvFBRGroupFvFBRMemberChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, fvFBRMemberFvFBRGroupPlan, fvFBRMemberFvFBRGroupState []FvFBRMemberFvFBRGroupResourceModel) []map[string]interface{} { + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.FvFBRMember.IsUnknown() { + tagAnnotationFvFBRMemberFvFBRGroupChildMap := NewAciObject() + tagTagFvFBRMemberFvFBRGroupChildMap := NewAciObject() + FvFBRMemberFvFBRGroupChildren := make([]map[string]interface{}, 0) + if !data.FvFBRMember.IsNull() && !data.FvFBRMember.IsUnknown() { fvFBRMemberIdentifiers := []FvFBRMemberIdentifier{} - for _, fvFBRMember := range fvFBRMemberPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !fvFBRMember.Annotation.IsUnknown() { - childMap["attributes"]["annotation"] = fvFBRMember.Annotation.ValueString() + for _, fvFBRMemberFvFBRGroup := range fvFBRMemberFvFBRGroupPlan { + if !fvFBRMemberFvFBRGroup.Annotation.IsNull() && !fvFBRMemberFvFBRGroup.Annotation.IsUnknown() { + childMap.Attributes["annotation"] = fvFBRMemberFvFBRGroup.Annotation.ValueString() } else { - childMap["attributes"]["annotation"] = globalAnnotation + childMap.Attributes["annotation"] = globalAnnotation + } + if !fvFBRMemberFvFBRGroup.Descr.IsNull() && !fvFBRMemberFvFBRGroup.Descr.IsUnknown() { + childMap.Attributes["descr"] = fvFBRMemberFvFBRGroup.Descr.ValueString() + } + if !fvFBRMemberFvFBRGroup.Name.IsNull() && !fvFBRMemberFvFBRGroup.Name.IsUnknown() { + childMap.Attributes["name"] = fvFBRMemberFvFBRGroup.Name.ValueString() + } + if !fvFBRMemberFvFBRGroup.NameAlias.IsNull() && !fvFBRMemberFvFBRGroup.NameAlias.IsUnknown() { + childMap.Attributes["nameAlias"] = fvFBRMemberFvFBRGroup.NameAlias.ValueString() + } + if !fvFBRMemberFvFBRGroup.RnhAddr.IsNull() && !fvFBRMemberFvFBRGroup.RnhAddr.IsUnknown() { + childMap.Attributes["rnhAddr"] = fvFBRMemberFvFBRGroup.RnhAddr.ValueString() } - if !fvFBRMember.Descr.IsUnknown() { - childMap["attributes"]["descr"] = fvFBRMember.Descr.ValueString() + var tagAnnotationFvFBRMemberFvFBRGroupPlan, tagAnnotationFvFBRMemberFvFBRGroupState []TagAnnotationFvFBRMemberFvFBRGroupResourceModel + fvFBRMemberFvFBRGroup.TagAnnotation.ElementsAs(ctx, &tagAnnotationFvFBRMemberFvFBRGroupPlan, false) + for _, fvFBRMembertagAnnotationState := range fvFBRMemberFvFBRGroupState { + fvFBRMembertagAnnotationState.TagAnnotation.ElementsAs(ctx, &tagAnnotationFvFBRMemberFvFBRGroupState, false) + if len(tagAnnotationFvFBRMemberFvFBRGroupPlan) == 0 && len(tagAnnotationFvFBRMemberFvFBRGroupState) == 1 { + tagAnnotationFvFBRMemberFvFBRGroupChildMap := NewAciObject() + tagAnnotationFvFBRMemberFvFBRGroupChildMap.Attributes["status"] = "deleted" + FvFBRMemberFvFBRGroupChildren = append(FvFBRMemberFvFBRGroupChildren, map[string]interface{}{"tagAnnotation": tagAnnotationFvFBRMemberFvFBRGroupChildMap}) + } } - if !fvFBRMember.Name.IsUnknown() { - childMap["attributes"]["name"] = fvFBRMember.Name.ValueString() + if !fvFBRMemberFvFBRGroup.TagAnnotation.IsNull() && !fvFBRMemberFvFBRGroup.TagAnnotation.IsUnknown() { + for _, tagAnnotationFvFBRMemberFvFBRGroup := range tagAnnotationFvFBRMemberFvFBRGroupPlan { + if !tagAnnotationFvFBRMemberFvFBRGroup.Key.IsNull() && !tagAnnotationFvFBRMemberFvFBRGroup.Key.IsUnknown() { + tagAnnotationFvFBRMemberFvFBRGroupChildMap.Attributes["key"] = tagAnnotationFvFBRMemberFvFBRGroup.Key.ValueString() + } + if !tagAnnotationFvFBRMemberFvFBRGroup.Value.IsNull() && !tagAnnotationFvFBRMemberFvFBRGroup.Value.IsUnknown() { + tagAnnotationFvFBRMemberFvFBRGroupChildMap.Attributes["value"] = tagAnnotationFvFBRMemberFvFBRGroup.Value.ValueString() + } + FvFBRMemberFvFBRGroupChildren = append(FvFBRMemberFvFBRGroupChildren, map[string]interface{}{"tagAnnotation": tagAnnotationFvFBRMemberFvFBRGroupChildMap}) + } } - if !fvFBRMember.NameAlias.IsUnknown() { - childMap["attributes"]["nameAlias"] = fvFBRMember.NameAlias.ValueString() + var tagTagFvFBRMemberFvFBRGroupPlan, tagTagFvFBRMemberFvFBRGroupState []TagTagFvFBRMemberFvFBRGroupResourceModel + fvFBRMemberFvFBRGroup.TagTag.ElementsAs(ctx, &tagTagFvFBRMemberFvFBRGroupPlan, false) + for _, fvFBRMembertagTagState := range fvFBRMemberFvFBRGroupState { + fvFBRMembertagTagState.TagTag.ElementsAs(ctx, &tagTagFvFBRMemberFvFBRGroupState, false) + if len(tagTagFvFBRMemberFvFBRGroupPlan) == 0 && len(tagTagFvFBRMemberFvFBRGroupState) == 1 { + tagTagFvFBRMemberFvFBRGroupChildMap := NewAciObject() + tagTagFvFBRMemberFvFBRGroupChildMap.Attributes["status"] = "deleted" + FvFBRMemberFvFBRGroupChildren = append(FvFBRMemberFvFBRGroupChildren, map[string]interface{}{"tagTag": tagTagFvFBRMemberFvFBRGroupChildMap}) + } } - if !fvFBRMember.RnhAddr.IsUnknown() { - childMap["attributes"]["rnhAddr"] = fvFBRMember.RnhAddr.ValueString() + if !fvFBRMemberFvFBRGroup.TagTag.IsNull() && !fvFBRMemberFvFBRGroup.TagTag.IsUnknown() { + for _, tagTagFvFBRMemberFvFBRGroup := range tagTagFvFBRMemberFvFBRGroupPlan { + if !tagTagFvFBRMemberFvFBRGroup.Key.IsNull() && !tagTagFvFBRMemberFvFBRGroup.Key.IsUnknown() { + tagTagFvFBRMemberFvFBRGroupChildMap.Attributes["key"] = tagTagFvFBRMemberFvFBRGroup.Key.ValueString() + } + if !tagTagFvFBRMemberFvFBRGroup.Value.IsNull() && !tagTagFvFBRMemberFvFBRGroup.Value.IsUnknown() { + tagTagFvFBRMemberFvFBRGroupChildMap.Attributes["value"] = tagTagFvFBRMemberFvFBRGroup.Value.ValueString() + } + FvFBRMemberFvFBRGroupChildren = append(FvFBRMemberFvFBRGroupChildren, map[string]interface{}{"tagTag": tagTagFvFBRMemberFvFBRGroupChildMap}) + } } + childMap.Children = FvFBRMemberFvFBRGroupChildren childPayloads = append(childPayloads, map[string]interface{}{"fvFBRMember": childMap}) fvFBRMemberIdentifier := FvFBRMemberIdentifier{} - fvFBRMemberIdentifier.RnhAddr = fvFBRMember.RnhAddr + fvFBRMemberIdentifier.RnhAddr = fvFBRMemberFvFBRGroup.RnhAddr fvFBRMemberIdentifiers = append(fvFBRMemberIdentifiers, fvFBRMemberIdentifier) } - for _, fvFBRMember := range fvFBRMemberState { + for _, fvFBRMember := range fvFBRMemberFvFBRGroupState { delete := true for _, fvFBRMemberIdentifier := range fvFBRMemberIdentifiers { if fvFBRMemberIdentifier.RnhAddr == fvFBRMember.RnhAddr { @@ -590,10 +833,10 @@ func getFvFBRGroupFvFBRMemberChildPayloads(ctx context.Context, diags *diag.Diag } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["rnhAddr"] = fvFBRMember.RnhAddr.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"fvFBRMember": childMap}) + fvFBRMemberChildMapForDelete := NewAciObject() + fvFBRMemberChildMapForDelete.Attributes["status"] = "deleted" + fvFBRMemberChildMapForDelete.Attributes["rnhAddr"] = fvFBRMember.RnhAddr.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"fvFBRMember": fvFBRMemberChildMapForDelete}) } } } else { @@ -602,25 +845,25 @@ func getFvFBRGroupFvFBRMemberChildPayloads(ctx context.Context, diags *diag.Diag return childPayloads } -func getFvFBRGroupTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvFBRGroupResourceModel) []map[string]interface{} { +func getFvFBRGroupTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, tagAnnotationFvFBRGroupPlan, tagAnnotationFvFBRGroupState []TagAnnotationFvFBRGroupResourceModel) []map[string]interface{} { + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationFvFBRGroup := range tagAnnotationFvFBRGroupPlan { + if !tagAnnotationFvFBRGroup.Key.IsNull() && !tagAnnotationFvFBRGroup.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationFvFBRGroup.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationFvFBRGroup.Value.IsNull() && !tagAnnotationFvFBRGroup.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationFvFBRGroup.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationFvFBRGroup.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationFvFBRGroupState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -629,10 +872,10 @@ func getFvFBRGroupTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -641,25 +884,25 @@ func getFvFBRGroupTagAnnotationChildPayloads(ctx context.Context, diags *diag.Di return childPayloads } -func getFvFBRGroupTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, tagTagPlan, tagTagState []TagTagFvFBRGroupResourceModel) []map[string]interface{} { +func getFvFBRGroupTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, tagTagFvFBRGroupPlan, tagTagFvFBRGroupState []TagTagFvFBRGroupResourceModel) []map[string]interface{} { + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + for _, tagTagFvFBRGroup := range tagTagFvFBRGroupPlan { + if !tagTagFvFBRGroup.Key.IsNull() && !tagTagFvFBRGroup.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagFvFBRGroup.Key.ValueString() } - if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + if !tagTagFvFBRGroup.Value.IsNull() && !tagTagFvFBRGroup.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagFvFBRGroup.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagFvFBRGroup.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagFvFBRGroupState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { @@ -668,10 +911,10 @@ func getFvFBRGroupTagTagChildPayloads(ctx context.Context, diags *diag.Diagnosti } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { diff --git a/internal/provider/resource_aci_vrf_fallback_route_group_member.go b/internal/provider/resource_aci_vrf_fallback_route_group_member.go index c78c3486b..31cb4b7e0 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group_member.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group_member.go @@ -13,6 +13,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -58,12 +59,34 @@ type TagAnnotationFvFBRMemberResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationFvFBRMemberResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationFvFBRMemberResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvFBRMemberResourceModelAttributeTypes()) +} + // TagTagFvFBRMemberResourceModel describes the resource data model for the children without relation ships. type TagTagFvFBRMemberResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagFvFBRMemberResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagFvFBRMemberResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvFBRMemberResourceModelAttributeTypes()) +} + type FvFBRMemberIdentifier struct { RnhAddr types.String } @@ -101,6 +124,7 @@ func (r *FvFBRMemberResource) Schema(ctx context.Context, req resource.SchemaReq Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the VRF Fallback Route Group Member object.`, @@ -110,6 +134,7 @@ func (r *FvFBRMemberResource) Schema(ctx context.Context, req resource.SchemaReq Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The description of the VRF Fallback Route Group Member object.`, }, @@ -118,6 +143,7 @@ func (r *FvFBRMemberResource) Schema(ctx context.Context, req resource.SchemaReq Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name of the VRF Fallback Route Group Member object.`, }, @@ -126,6 +152,7 @@ func (r *FvFBRMemberResource) Schema(ctx context.Context, req resource.SchemaReq Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the VRF Fallback Route Group Member object.`, }, @@ -133,6 +160,7 @@ func (r *FvFBRMemberResource) Schema(ctx context.Context, req resource.SchemaReq Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The address of the VRF Fallback Route Group Member object.`, @@ -150,6 +178,7 @@ func (r *FvFBRMemberResource) Schema(ctx context.Context, req resource.SchemaReq Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -157,6 +186,7 @@ func (r *FvFBRMemberResource) Schema(ctx context.Context, req resource.SchemaReq Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -176,6 +206,7 @@ func (r *FvFBRMemberResource) Schema(ctx context.Context, req resource.SchemaReq Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -183,6 +214,7 @@ func (r *FvFBRMemberResource) Schema(ctx context.Context, req resource.SchemaReq Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -362,7 +394,7 @@ func (r *FvFBRMemberResource) ImportState(ctx context.Context, req resource.Impo } func getAndSetFvFBRMemberAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *FvFBRMemberResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "fvFBRMember,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "fvFBRMember,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -392,7 +424,24 @@ func getAndSetFvFBRMemberAttributes(ctx context.Context, diags *diag.Diagnostics data.RnhAddr = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.Descr.IsUnknown() { + data.Descr = types.StringNull() + } + if data.Name.IsUnknown() { + data.Name = types.StringNull() + } + if data.NameAlias.IsUnknown() { + data.NameAlias = types.StringNull() + } + if data.RnhAddr.IsUnknown() { + data.RnhAddr = types.StringNull() + } + TagAnnotationFvFBRMember := TagAnnotationFvFBRMemberResourceModel{} TagAnnotationFvFBRMemberList := make([]TagAnnotationFvFBRMemberResourceModel, 0) + TagTagFvFBRMember := TagTagFvFBRMemberResourceModel{} TagTagFvFBRMemberList := make([]TagTagFvFBRMemberResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -401,7 +450,6 @@ func getAndSetFvFBRMemberAttributes(ctx context.Context, diags *diag.Diagnostics for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "tagAnnotation" { - TagAnnotationFvFBRMember := TagAnnotationFvFBRMemberResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationFvFBRMember.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -409,11 +457,11 @@ func getAndSetFvFBRMemberAttributes(ctx context.Context, diags *diag.Diagnostics if childAttributeName == "value" { TagAnnotationFvFBRMember.Value = basetypes.NewStringValue(childAttributeValue.(string)) } + } TagAnnotationFvFBRMemberList = append(TagAnnotationFvFBRMemberList, TagAnnotationFvFBRMember) } if childClassName == "tagTag" { - TagTagFvFBRMember := TagTagFvFBRMemberResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagFvFBRMember.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -421,6 +469,7 @@ func getAndSetFvFBRMemberAttributes(ctx context.Context, diags *diag.Diagnostics if childAttributeName == "value" { TagTagFvFBRMember.Value = basetypes.NewStringValue(childAttributeValue.(string)) } + } TagTagFvFBRMemberList = append(TagTagFvFBRMemberList, TagTagFvFBRMember) } @@ -473,25 +522,24 @@ func setFvFBRMemberId(ctx context.Context, data *FvFBRMemberResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getFvFBRMemberTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRMemberResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvFBRMemberResourceModel) []map[string]interface{} { - +func getFvFBRMemberTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRMemberResourceModel, tagAnnotationFvFBRMemberPlan, tagAnnotationFvFBRMemberState []TagAnnotationFvFBRMemberResourceModel) []map[string]interface{} { + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationFvFBRMember := range tagAnnotationFvFBRMemberPlan { + if !tagAnnotationFvFBRMember.Key.IsNull() && !tagAnnotationFvFBRMember.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationFvFBRMember.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationFvFBRMember.Value.IsNull() && !tagAnnotationFvFBRMember.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationFvFBRMember.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationFvFBRMember.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationFvFBRMemberState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -500,10 +548,10 @@ func getFvFBRMemberTagAnnotationChildPayloads(ctx context.Context, diags *diag.D } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -512,25 +560,25 @@ func getFvFBRMemberTagAnnotationChildPayloads(ctx context.Context, diags *diag.D return childPayloads } -func getFvFBRMemberTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRMemberResourceModel, tagTagPlan, tagTagState []TagTagFvFBRMemberResourceModel) []map[string]interface{} { +func getFvFBRMemberTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRMemberResourceModel, tagTagFvFBRMemberPlan, tagTagFvFBRMemberState []TagTagFvFBRMemberResourceModel) []map[string]interface{} { + childMap := NewAciObject() childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + for _, tagTagFvFBRMember := range tagTagFvFBRMemberPlan { + if !tagTagFvFBRMember.Key.IsNull() && !tagTagFvFBRMember.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagFvFBRMember.Key.ValueString() } - if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + if !tagTagFvFBRMember.Value.IsNull() && !tagTagFvFBRMember.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagFvFBRMember.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagFvFBRMember.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagFvFBRMemberState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { @@ -539,10 +587,10 @@ func getFvFBRMemberTagTagChildPayloads(ctx context.Context, diags *diag.Diagnost } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { From 1c8bfcce6321677290cd9b924239cecb0c45ad60 Mon Sep 17 00:00:00 2001 From: Shreyas Date: Mon, 6 May 2024 14:17:27 -0600 Subject: [PATCH 09/20] [ignore] Moved declaration of childmap under loop over plan --- docs/data-sources/endpoint_tag_ip.md | 8 - docs/data-sources/endpoint_tag_mac.md | 8 - ...nal_management_network_instance_profile.md | 8 - .../external_management_network_subnet.md | 8 - docs/data-sources/l3out_consumer_label.md | 8 - .../data-sources/l3out_redistribute_policy.md | 8 - docs/data-sources/out_of_band_contract.md | 8 - docs/data-sources/pim_route_map_entry.md | 8 - docs/data-sources/pim_route_map_policy.md | 8 - ...lation_to_consumed_out_of_band_contract.md | 8 - .../relation_to_fallback_route_group.md | 8 - docs/data-sources/vrf_fallback_route_group.md | 8 - .../vrf_fallback_route_group_member.md | 8 - docs/resources/endpoint_tag_ip.md | 26 - docs/resources/endpoint_tag_mac.md | 26 - ...nal_management_network_instance_profile.md | 26 - .../external_management_network_subnet.md | 26 - docs/resources/l3out_consumer_label.md | 26 - docs/resources/l3out_redistribute_policy.md | 26 - docs/resources/out_of_band_contract.md | 26 - docs/resources/pim_route_map_entry.md | 26 - docs/resources/pim_route_map_policy.md | 26 - ...lation_to_consumed_out_of_band_contract.md | 26 - .../relation_to_fallback_route_group.md | 26 - docs/resources/vrf_fallback_route_group.md | 26 - .../vrf_fallback_route_group_member.md | 26 - .../resource-all-attributes.tf | 12 - .../resource-all-attributes.tf | 12 - .../resource-all-attributes.tf | 12 - .../resource-all-attributes.tf | 12 - .../resource-all-attributes.tf | 12 - .../resource-all-attributes.tf | 12 - .../resource-all-attributes.tf | 12 - .../resource-all-attributes.tf | 12 - .../resource-all-attributes.tf | 12 - .../resource-all-attributes.tf | 12 - .../resource-all-attributes.tf | 12 - .../resource-all-attributes.tf | 12 - .../resource-all-attributes.tf | 12 - gen/definitions/classes.yaml | 13 + gen/generator.go | 2 +- gen/templates/resource.go.tmpl | 89 ++- gen/testvars/fvEpIpTag.yaml | 15 - gen/testvars/fvEpMacTag.yaml | 15 - gen/testvars/fvFBRGroup.yaml | 14 - gen/testvars/fvFBRMember.yaml | 15 - gen/testvars/l3extConsLbl.yaml | 15 - gen/testvars/l3extRsOutToFBRGroup.yaml | 15 - gen/testvars/l3extRsRedistributePol.yaml | 15 - gen/testvars/mgmtInstP.yaml | 14 - gen/testvars/mgmtRsOoBCons.yaml | 15 - gen/testvars/mgmtSubnet.yaml | 15 - gen/testvars/pimRouteMapEntry.yaml | 15 - gen/testvars/pimRouteMapPol.yaml | 15 - gen/testvars/vzOOBBrCP.yaml | 15 - .../data_source_aci_endpoint_tag_ip.go | 32 -- .../data_source_aci_endpoint_tag_mac.go | 32 -- ...nal_management_network_instance_profile.go | 32 -- ..._aci_external_management_network_subnet.go | 32 -- .../data_source_aci_l3out_consumer_label.go | 32 -- ...ta_source_aci_l3out_redistribute_policy.go | 32 -- .../data_source_aci_out_of_band_contract.go | 32 -- .../data_source_aci_pim_route_map_entry.go | 32 -- .../data_source_aci_pim_route_map_policy.go | 32 -- ...lation_to_consumed_out_of_band_contract.go | 32 -- ...ce_aci_relation_to_fallback_route_group.go | 32 -- ...ata_source_aci_vrf_fallback_route_group.go | 32 -- ...rce_aci_vrf_fallback_route_group_member.go | 32 -- .../resource_aci_communication_policy.go | 540 ++---------------- .../provider/resource_aci_endpoint_tag_ip.go | 271 +-------- .../resource_aci_endpoint_tag_ip_test.go | 147 ----- .../provider/resource_aci_endpoint_tag_mac.go | 271 +-------- .../resource_aci_endpoint_tag_mac_test.go | 147 ----- ...nal_management_network_instance_profile.go | 415 +------------- ...anagement_network_instance_profile_test.go | 62 -- ..._aci_external_management_network_subnet.go | 269 +-------- ...external_management_network_subnet_test.go | 141 ----- .../resource_aci_l3out_consumer_label.go | 275 +-------- .../resource_aci_l3out_consumer_label_test.go | 147 ----- .../resource_aci_l3out_redistribute_policy.go | 255 +-------- ...urce_aci_l3out_redistribute_policy_test.go | 141 ----- .../resource_aci_out_of_band_contract.go | 277 +-------- .../resource_aci_out_of_band_contract_test.go | 145 ----- .../resource_aci_pim_route_map_entry.go | 277 +-------- .../resource_aci_pim_route_map_entry_test.go | 149 ----- .../resource_aci_pim_route_map_policy.go | 271 +-------- .../resource_aci_pim_route_map_policy_test.go | 143 ----- ...lation_to_consumed_out_of_band_contract.go | 255 +-------- ...n_to_consumed_out_of_band_contract_test.go | 137 ----- ...ce_aci_relation_to_fallback_route_group.go | 263 +-------- ...i_relation_to_fallback_route_group_test.go | 135 ----- .../resource_aci_vrf_fallback_route_group.go | 439 +------------- ...rce_aci_vrf_fallback_route_group_member.go | 269 +-------- ...ci_vrf_fallback_route_group_member_test.go | 141 ----- ...ource_aci_vrf_fallback_route_group_test.go | 68 --- 95 files changed, 278 insertions(+), 7083 deletions(-) diff --git a/docs/data-sources/endpoint_tag_ip.md b/docs/data-sources/endpoint_tag_ip.md index 92bd7d66a..41eb358bd 100644 --- a/docs/data-sources/endpoint_tag_ip.md +++ b/docs/data-sources/endpoint_tag_ip.md @@ -54,11 +54,3 @@ data "aci_endpoint_tag_ip" "example_tenant" { * `id_attribute` (id) - (string) The identifier of the Endpoint Tag Ip object. * `name` (name) - (string) The name of the Endpoint Tag Ip object. * `name_alias` (nameAlias) - (string) The name alias of the Endpoint Tag Ip object. - -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/endpoint_tag_mac.md b/docs/data-sources/endpoint_tag_mac.md index 65de071a0..14239b98a 100644 --- a/docs/data-sources/endpoint_tag_mac.md +++ b/docs/data-sources/endpoint_tag_mac.md @@ -54,11 +54,3 @@ data "aci_endpoint_tag_mac" "example_tenant" { * `id_attribute` (id) - (string) The identifier of the Endpoint Tag Mac object. * `name` (name) - (string) The name of the Endpoint Tag Mac object. * `name_alias` (nameAlias) - (string) The name alias of the Endpoint Tag Mac object. - -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/external_management_network_instance_profile.md b/docs/data-sources/external_management_network_instance_profile.md index 0b13ab7d4..a2ca8fb39 100644 --- a/docs/data-sources/external_management_network_instance_profile.md +++ b/docs/data-sources/external_management_network_instance_profile.md @@ -54,11 +54,3 @@ data "aci_external_management_network_instance_profile" "example" { * `annotation` (annotation) - (string) The annotation of the Relation To Consumed Out Of Band Contract object. * `priority` (prio) - (string) The Quality of service (QoS) priority class ID. QoS refers to the capability of a network to provide better service to selected network traffic over various technologies. The primary goal of QoS is to provide priority including dedicated bandwidth, controlled jitter and latency (required by some real-time and interactive traffic), and improved loss characteristics. You can configure the bandwidth of each QoS level using QoS profiles. * `out_of_band_contract_name` (tnVzOOBBrCPName) - (string) The name of the Out Of Band Contract object. - -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/external_management_network_subnet.md b/docs/data-sources/external_management_network_subnet.md index 663394bb0..761df2bfd 100644 --- a/docs/data-sources/external_management_network_subnet.md +++ b/docs/data-sources/external_management_network_subnet.md @@ -52,11 +52,3 @@ data "aci_external_management_network_subnet" "example_external_management_netwo * `description` (descr) - (string) The description of the External Management Network Subnet object. * `name` (name) - (string) The name of the External Management Network Subnet object. * `name_alias` (nameAlias) - (string) The name alias of the External Management Network Subnet object. - -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/l3out_consumer_label.md b/docs/data-sources/l3out_consumer_label.md index d9031ba6e..105b1e6cd 100644 --- a/docs/data-sources/l3out_consumer_label.md +++ b/docs/data-sources/l3out_consumer_label.md @@ -57,11 +57,3 @@ data "aci_l3out_consumer_label" "example_l3_outside" { * `owner_key` (ownerKey) - (string) The key for enabling clients to own their data for entity correlation. * `owner_tag` (ownerTag) - (string) A tag for enabling clients to add their own data. For example, to indicate who created this object. * `tag` (tag) - (string) Specifies the color of a policy label. - -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/l3out_redistribute_policy.md b/docs/data-sources/l3out_redistribute_policy.md index 521d2d3ca..0d1e91bb4 100644 --- a/docs/data-sources/l3out_redistribute_policy.md +++ b/docs/data-sources/l3out_redistribute_policy.md @@ -52,11 +52,3 @@ data "aci_l3out_redistribute_policy" "example_l3_outside" { * `id` - (string) The distinguished name (DN) of the L3out Redistribute Policy object. * `annotation` (annotation) - (string) The annotation of the L3out Redistribute Policy object. - -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/out_of_band_contract.md b/docs/data-sources/out_of_band_contract.md index 5265a5b02..50b2218bf 100644 --- a/docs/data-sources/out_of_band_contract.md +++ b/docs/data-sources/out_of_band_contract.md @@ -54,11 +54,3 @@ data "aci_out_of_band_contract" "example" { * `priority` (prio) - (string) The priority of the Out Of Band Contract object. * `scope` (scope) - (string) Represents the scope of this contract. If the scope is set as application-profile, the epg can only communicate with epgs in the same application-profile. * `target_dscp` (targetDscp) - (string) The target DSCP value of the Out Of Band Contract object. - -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/pim_route_map_entry.md b/docs/data-sources/pim_route_map_entry.md index b999b7b7a..fe80bd386 100644 --- a/docs/data-sources/pim_route_map_entry.md +++ b/docs/data-sources/pim_route_map_entry.md @@ -56,11 +56,3 @@ data "aci_pim_route_map_entry" "example_pim_route_map_policy" { * `name_alias` (nameAlias) - (string) The name alias of the Pim Route Map Entry object. * `rendezvous_point_ip` (rp) - (string) The rendezvous point ip of the Pim Route Map Entry object. * `source_ip` (src) - (string) The source ip of the Pim Route Map Entry object. - -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/pim_route_map_policy.md b/docs/data-sources/pim_route_map_policy.md index a082c1702..b99ae6323 100644 --- a/docs/data-sources/pim_route_map_policy.md +++ b/docs/data-sources/pim_route_map_policy.md @@ -53,11 +53,3 @@ data "aci_pim_route_map_policy" "example_tenant" { * `name_alias` (nameAlias) - (string) The name alias of the Pim Route Map Policy object. * `owner_key` (ownerKey) - (string) The key for enabling clients to own their data for entity correlation. * `owner_tag` (ownerTag) - (string) A tag for enabling clients to add their own data. For example, to indicate who created this object. - -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/relation_to_consumed_out_of_band_contract.md b/docs/data-sources/relation_to_consumed_out_of_band_contract.md index 9e08ccb8e..a60b57ef8 100644 --- a/docs/data-sources/relation_to_consumed_out_of_band_contract.md +++ b/docs/data-sources/relation_to_consumed_out_of_band_contract.md @@ -50,11 +50,3 @@ data "aci_relation_to_consumed_out_of_band_contract" "example_external_managemen * `id` - (string) The distinguished name (DN) of the Relation To Consumed Out Of Band Contract object. * `annotation` (annotation) - (string) The annotation of the Relation To Consumed Out Of Band Contract object. * `priority` (prio) - (string) The Quality of service (QoS) priority class ID. QoS refers to the capability of a network to provide better service to selected network traffic over various technologies. The primary goal of QoS is to provide priority including dedicated bandwidth, controlled jitter and latency (required by some real-time and interactive traffic), and improved loss characteristics. You can configure the bandwidth of each QoS level using QoS profiles. - -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/relation_to_fallback_route_group.md b/docs/data-sources/relation_to_fallback_route_group.md index da9da0235..a74c9d414 100644 --- a/docs/data-sources/relation_to_fallback_route_group.md +++ b/docs/data-sources/relation_to_fallback_route_group.md @@ -49,11 +49,3 @@ data "aci_relation_to_fallback_route_group" "example_l3_outside" { * `id` - (string) The distinguished name (DN) of the Relation To Fallback Route Group object. * `annotation` (annotation) - (string) The annotation of the Relation To Fallback Route Group object. - -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/vrf_fallback_route_group.md b/docs/data-sources/vrf_fallback_route_group.md index 03c295100..ed3f39169 100644 --- a/docs/data-sources/vrf_fallback_route_group.md +++ b/docs/data-sources/vrf_fallback_route_group.md @@ -58,11 +58,3 @@ data "aci_vrf_fallback_route_group" "example_vrf" { * `name` (name) - (string) The name of the VRF Fallback Route Group Member object. * `name_alias` (nameAlias) - (string) The name alias of the VRF Fallback Route Group Member object. * `fallback_member` (rnhAddr) - (string) The address of the VRF Fallback Route Group Member object. - -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/vrf_fallback_route_group_member.md b/docs/data-sources/vrf_fallback_route_group_member.md index 11d8a2c17..b39ca3340 100644 --- a/docs/data-sources/vrf_fallback_route_group_member.md +++ b/docs/data-sources/vrf_fallback_route_group_member.md @@ -52,11 +52,3 @@ data "aci_vrf_fallback_route_group_member" "example_vrf_fallback_route_group" { * `description` (descr) - (string) The description of the VRF Fallback Route Group Member object. * `name` (name) - (string) The name of the VRF Fallback Route Group Member object. * `name_alias` (nameAlias) - (string) The name alias of the VRF Fallback Route Group Member object. - -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. diff --git a/docs/resources/endpoint_tag_ip.md b/docs/resources/endpoint_tag_ip.md index 369bbb796..edb78f5a9 100644 --- a/docs/resources/endpoint_tag_ip.md +++ b/docs/resources/endpoint_tag_ip.md @@ -55,18 +55,6 @@ resource "aci_endpoint_tag_ip" "full_example_tenant" { ip = "10.0.0.2" name = "name" name_alias = "name_alias" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } ``` @@ -94,20 +82,6 @@ All examples for the Endpoint Tag Ip resource can be found in the [examples](htt * `name` (name) - (string) The name of the Endpoint Tag Ip object. * `name_alias` (nameAlias) - (string) The name alias of the Endpoint Tag Ip object. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - ## Importing An existing Endpoint Tag Ip can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/endpoint_tag_mac.md b/docs/resources/endpoint_tag_mac.md index ee16a8ce0..3069a7b7f 100644 --- a/docs/resources/endpoint_tag_mac.md +++ b/docs/resources/endpoint_tag_mac.md @@ -55,18 +55,6 @@ resource "aci_endpoint_tag_mac" "full_example_tenant" { mac = "00:00:00:00:00:01" name = "name" name_alias = "name_alias" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } ``` @@ -94,20 +82,6 @@ All examples for the Endpoint Tag Mac resource can be found in the [examples](ht * `name` (name) - (string) The name of the Endpoint Tag Mac object. * `name_alias` (nameAlias) - (string) The name alias of the Endpoint Tag Mac object. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - ## Importing An existing Endpoint Tag Mac can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/external_management_network_instance_profile.md b/docs/resources/external_management_network_instance_profile.md index 17c562f06..5ee35b4a2 100644 --- a/docs/resources/external_management_network_instance_profile.md +++ b/docs/resources/external_management_network_instance_profile.md @@ -58,18 +58,6 @@ resource "aci_external_management_network_instance_profile" "full_example" { out_of_band_contract_name = aci_out_of_band_contract.example.name } ] - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } ``` @@ -110,20 +98,6 @@ All examples for the External Management Network Instance Profile resource can b - Default: `unspecified` - Valid Values: `level1`, `level2`, `level3`, `level4`, `level5`, `level6`, `unspecified`. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - ## Importing An existing External Management Network Instance Profile can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/external_management_network_subnet.md b/docs/resources/external_management_network_subnet.md index 92432a2dd..9ae8a43f0 100644 --- a/docs/resources/external_management_network_subnet.md +++ b/docs/resources/external_management_network_subnet.md @@ -53,18 +53,6 @@ resource "aci_external_management_network_subnet" "full_example_external_managem ip = "1.1.1.0/24" name = "name" name_alias = "name_alias" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } ``` @@ -91,20 +79,6 @@ All examples for the External Management Network Subnet resource can be found in * `name` (name) - (string) The name of the External Management Network Subnet object. * `name_alias` (nameAlias) - (string) The name alias of the External Management Network Subnet object. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - ## Importing An existing External Management Network Subnet can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/l3out_consumer_label.md b/docs/resources/l3out_consumer_label.md index 1cb74b2f5..f3fd0ee39 100644 --- a/docs/resources/l3out_consumer_label.md +++ b/docs/resources/l3out_consumer_label.md @@ -58,18 +58,6 @@ resource "aci_l3out_consumer_label" "full_example_l3_outside" { owner_key = "owner_key" owner_tag = "owner_tag" tag = "lemon-chiffon" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } ``` @@ -102,20 +90,6 @@ All examples for the L3out Consumer Label resource can be found in the [examples * `tag` (tag) - (string) Specifies the color of a policy label. - Valid Values: `alice-blue`, `antique-white`, `aqua`, `aquamarine`, `azure`, `beige`, `bisque`, `black`, `blanched-almond`, `blue`, `blue-violet`, `brown`, `burlywood`, `cadet-blue`, `chartreuse`, `chocolate`, `coral`, `cornflower-blue`, `cornsilk`, `crimson`, `cyan`, `dark-blue`, `dark-cyan`, `dark-goldenrod`, `dark-gray`, `dark-green`, `dark-khaki`, `dark-magenta`, `dark-olive-green`, `dark-orange`, `dark-orchid`, `dark-red`, `dark-salmon`, `dark-sea-green`, `dark-slate-blue`, `dark-slate-gray`, `dark-turquoise`, `dark-violet`, `deep-pink`, `deep-sky-blue`, `dim-gray`, `dodger-blue`, `fire-brick`, `floral-white`, `forest-green`, `fuchsia`, `gainsboro`, `ghost-white`, `gold`, `goldenrod`, `gray`, `green`, `green-yellow`, `honeydew`, `hot-pink`, `indian-red`, `indigo`, `ivory`, `khaki`, `lavender`, `lavender-blush`, `lawn-green`, `lemon-chiffon`, `light-blue`, `light-coral`, `light-cyan`, `light-goldenrod-yellow`, `light-gray`, `light-green`, `light-pink`, `light-salmon`, `light-sea-green`, `light-sky-blue`, `light-slate-gray`, `light-steel-blue`, `light-yellow`, `lime`, `lime-green`, `linen`, `magenta`, `maroon`, `medium-aquamarine`, `medium-blue`, `medium-orchid`, `medium-purple`, `medium-sea-green`, `medium-slate-blue`, `medium-spring-green`, `medium-turquoise`, `medium-violet-red`, `midnight-blue`, `mint-cream`, `misty-rose`, `moccasin`, `navajo-white`, `navy`, `old-lace`, `olive`, `olive-drab`, `orange`, `orange-red`, `orchid`, `pale-goldenrod`, `pale-green`, `pale-turquoise`, `pale-violet-red`, `papaya-whip`, `peachpuff`, `peru`, `pink`, `plum`, `powder-blue`, `purple`, `red`, `rosy-brown`, `royal-blue`, `saddle-brown`, `salmon`, `sandy-brown`, `sea-green`, `seashell`, `sienna`, `silver`, `sky-blue`, `slate-blue`, `slate-gray`, `snow`, `spring-green`, `steel-blue`, `tan`, `teal`, `thistle`, `tomato`, `turquoise`, `violet`, `wheat`, `white`, `white-smoke`, `yellow`, `yellow-green`. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - ## Importing An existing L3out Consumer Label can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/l3out_redistribute_policy.md b/docs/resources/l3out_redistribute_policy.md index 270843a8b..e02e08bb6 100644 --- a/docs/resources/l3out_redistribute_policy.md +++ b/docs/resources/l3out_redistribute_policy.md @@ -52,18 +52,6 @@ resource "aci_l3out_redistribute_policy" "full_example_l3_outside" { annotation = "annotation" source = "direct" route_control_profile_name = aci_route_control_profile.example.name - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } ``` @@ -89,20 +77,6 @@ All examples for the L3out Redistribute Policy resource can be found in the [exa * `annotation` (annotation) - (string) The annotation of the L3out Redistribute Policy object. - Default: `orchestrator:terraform` -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - ## Importing An existing L3out Redistribute Policy can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/out_of_band_contract.md b/docs/resources/out_of_band_contract.md index 2f04bbf76..047ac4817 100644 --- a/docs/resources/out_of_band_contract.md +++ b/docs/resources/out_of_band_contract.md @@ -56,18 +56,6 @@ resource "aci_out_of_band_contract" "full_example" { priority = "level1" scope = "application-profile" target_dscp = "AF11" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } ``` @@ -105,20 +93,6 @@ All examples for the Out Of Band Contract resource can be found in the [examples - Default: `unspecified` - Valid Values: `AF11`, `AF12`, `AF13`, `AF21`, `AF22`, `AF23`, `AF31`, `AF32`, `AF33`, `AF41`, `AF42`, `AF43`, `CS0`, `CS1`, `CS2`, `CS3`, `CS4`, `CS5`, `CS6`, `CS7`, `EF`, `VA`, `unspecified`. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - ## Importing An existing Out Of Band Contract can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/pim_route_map_entry.md b/docs/resources/pim_route_map_entry.md index 0656563e3..eb284d82c 100644 --- a/docs/resources/pim_route_map_entry.md +++ b/docs/resources/pim_route_map_entry.md @@ -57,18 +57,6 @@ resource "aci_pim_route_map_entry" "full_example_pim_route_map_policy" { order = "1" rendezvous_point_ip = "0.0.0.0" source_ip = "1.1.1.1/30" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } ``` @@ -101,20 +89,6 @@ All examples for the Pim Route Map Entry resource can be found in the [examples] * `rendezvous_point_ip` (rp) - (string) The rendezvous point ip of the Pim Route Map Entry object. * `source_ip` (src) - (string) The source ip of the Pim Route Map Entry object. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - ## Importing An existing Pim Route Map Entry can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/pim_route_map_policy.md b/docs/resources/pim_route_map_policy.md index ab3d1c569..c44f7dbc4 100644 --- a/docs/resources/pim_route_map_policy.md +++ b/docs/resources/pim_route_map_policy.md @@ -54,18 +54,6 @@ resource "aci_pim_route_map_policy" "full_example_tenant" { name_alias = "name_alias" owner_key = "owner_key" owner_tag = "owner_tag" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } ``` @@ -93,20 +81,6 @@ All examples for the Pim Route Map Policy resource can be found in the [examples * `owner_key` (ownerKey) - (string) The key for enabling clients to own their data for entity correlation. * `owner_tag` (ownerTag) - (string) A tag for enabling clients to add their own data. For example, to indicate who created this object. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - ## Importing An existing Pim Route Map Policy can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/relation_to_consumed_out_of_band_contract.md b/docs/resources/relation_to_consumed_out_of_band_contract.md index f9244a156..d825b458b 100644 --- a/docs/resources/relation_to_consumed_out_of_band_contract.md +++ b/docs/resources/relation_to_consumed_out_of_band_contract.md @@ -51,18 +51,6 @@ resource "aci_relation_to_consumed_out_of_band_contract" "full_example_external_ annotation = "annotation" priority = "level1" out_of_band_contract_name = aci_out_of_band_contract.example.name - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } ``` @@ -89,20 +77,6 @@ All examples for the Relation To Consumed Out Of Band Contract resource can be f - Default: `unspecified` - Valid Values: `level1`, `level2`, `level3`, `level4`, `level5`, `level6`, `unspecified`. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - ## Importing An existing Relation To Consumed Out Of Band Contract can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/relation_to_fallback_route_group.md b/docs/resources/relation_to_fallback_route_group.md index c7acf8bd1..db02e08cf 100644 --- a/docs/resources/relation_to_fallback_route_group.md +++ b/docs/resources/relation_to_fallback_route_group.md @@ -50,18 +50,6 @@ resource "aci_relation_to_fallback_route_group" "full_example_l3_outside" { parent_dn = aci_l3_outside.example.id annotation = "annotation" target_dn = aci_vrf_fallback_route_group.test.id - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } ``` @@ -85,20 +73,6 @@ All examples for the Relation To Fallback Route Group resource can be found in t * `annotation` (annotation) - (string) The annotation of the Relation To Fallback Route Group object. - Default: `orchestrator:terraform` -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - ## Importing An existing Relation To Fallback Route Group can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/vrf_fallback_route_group.md b/docs/resources/vrf_fallback_route_group.md index dbfacd95f..c3db9c4f6 100644 --- a/docs/resources/vrf_fallback_route_group.md +++ b/docs/resources/vrf_fallback_route_group.md @@ -61,18 +61,6 @@ resource "aci_vrf_fallback_route_group" "full_example_vrf" { fallback_member = "2.2.2.2" } ] - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } ``` @@ -112,20 +100,6 @@ All examples for the VRF Fallback Route Group resource can be found in the [exam * `name` (name) - (string) The name of the VRF Fallback Route Group Member object. * `name_alias` (nameAlias) - (string) The name alias of the VRF Fallback Route Group Member object. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - ## Importing An existing VRF Fallback Route Group can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/vrf_fallback_route_group_member.md b/docs/resources/vrf_fallback_route_group_member.md index 5a056816e..401aa0ed7 100644 --- a/docs/resources/vrf_fallback_route_group_member.md +++ b/docs/resources/vrf_fallback_route_group_member.md @@ -54,18 +54,6 @@ resource "aci_vrf_fallback_route_group_member" "full_example_vrf_fallback_route_ name = "name" name_alias = "name_alias" fallback_member = "2.2.2.3" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } ``` @@ -92,20 +80,6 @@ All examples for the VRF Fallback Route Group Member resource can be found in th * `name` (name) - (string) The name of the VRF Fallback Route Group Member object. * `name_alias` (nameAlias) - (string) The name alias of the VRF Fallback Route Group Member object. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - -* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - - #### Required #### - - * `key` (key) - (string) The key used to uniquely identify this configuration object. - * `value` (value) - (string) The value of the property. - ## Importing An existing VRF Fallback Route Group Member can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/examples/resources/aci_endpoint_tag_ip/resource-all-attributes.tf b/examples/resources/aci_endpoint_tag_ip/resource-all-attributes.tf index 847c24241..35fe480cc 100644 --- a/examples/resources/aci_endpoint_tag_ip/resource-all-attributes.tf +++ b/examples/resources/aci_endpoint_tag_ip/resource-all-attributes.tf @@ -7,16 +7,4 @@ resource "aci_endpoint_tag_ip" "full_example_tenant" { ip = "10.0.0.2" name = "name" name_alias = "name_alias" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } diff --git a/examples/resources/aci_endpoint_tag_mac/resource-all-attributes.tf b/examples/resources/aci_endpoint_tag_mac/resource-all-attributes.tf index cb5fcf1f3..a1ba38d8c 100644 --- a/examples/resources/aci_endpoint_tag_mac/resource-all-attributes.tf +++ b/examples/resources/aci_endpoint_tag_mac/resource-all-attributes.tf @@ -7,16 +7,4 @@ resource "aci_endpoint_tag_mac" "full_example_tenant" { mac = "00:00:00:00:00:01" name = "name" name_alias = "name_alias" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } diff --git a/examples/resources/aci_external_management_network_instance_profile/resource-all-attributes.tf b/examples/resources/aci_external_management_network_instance_profile/resource-all-attributes.tf index 55b9ca15a..321155433 100644 --- a/examples/resources/aci_external_management_network_instance_profile/resource-all-attributes.tf +++ b/examples/resources/aci_external_management_network_instance_profile/resource-all-attributes.tf @@ -12,16 +12,4 @@ resource "aci_external_management_network_instance_profile" "full_example" { out_of_band_contract_name = aci_out_of_band_contract.example.name } ] - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } diff --git a/examples/resources/aci_external_management_network_subnet/resource-all-attributes.tf b/examples/resources/aci_external_management_network_subnet/resource-all-attributes.tf index 95e868212..d5186529c 100644 --- a/examples/resources/aci_external_management_network_subnet/resource-all-attributes.tf +++ b/examples/resources/aci_external_management_network_subnet/resource-all-attributes.tf @@ -6,16 +6,4 @@ resource "aci_external_management_network_subnet" "full_example_external_managem ip = "1.1.1.0/24" name = "name" name_alias = "name_alias" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } diff --git a/examples/resources/aci_l3out_consumer_label/resource-all-attributes.tf b/examples/resources/aci_l3out_consumer_label/resource-all-attributes.tf index 09a5c84eb..605ce7b03 100644 --- a/examples/resources/aci_l3out_consumer_label/resource-all-attributes.tf +++ b/examples/resources/aci_l3out_consumer_label/resource-all-attributes.tf @@ -9,16 +9,4 @@ resource "aci_l3out_consumer_label" "full_example_l3_outside" { owner_key = "owner_key" owner_tag = "owner_tag" tag = "lemon-chiffon" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } diff --git a/examples/resources/aci_l3out_redistribute_policy/resource-all-attributes.tf b/examples/resources/aci_l3out_redistribute_policy/resource-all-attributes.tf index 65ac30034..cbb24119d 100644 --- a/examples/resources/aci_l3out_redistribute_policy/resource-all-attributes.tf +++ b/examples/resources/aci_l3out_redistribute_policy/resource-all-attributes.tf @@ -4,16 +4,4 @@ resource "aci_l3out_redistribute_policy" "full_example_l3_outside" { annotation = "annotation" source = "direct" route_control_profile_name = aci_route_control_profile.example.name - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } diff --git a/examples/resources/aci_out_of_band_contract/resource-all-attributes.tf b/examples/resources/aci_out_of_band_contract/resource-all-attributes.tf index 293499941..092e6104c 100644 --- a/examples/resources/aci_out_of_band_contract/resource-all-attributes.tf +++ b/examples/resources/aci_out_of_band_contract/resource-all-attributes.tf @@ -10,16 +10,4 @@ resource "aci_out_of_band_contract" "full_example" { priority = "level1" scope = "application-profile" target_dscp = "AF11" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } diff --git a/examples/resources/aci_pim_route_map_entry/resource-all-attributes.tf b/examples/resources/aci_pim_route_map_entry/resource-all-attributes.tf index c3e6636ed..b2f732235 100644 --- a/examples/resources/aci_pim_route_map_entry/resource-all-attributes.tf +++ b/examples/resources/aci_pim_route_map_entry/resource-all-attributes.tf @@ -10,16 +10,4 @@ resource "aci_pim_route_map_entry" "full_example_pim_route_map_policy" { order = "1" rendezvous_point_ip = "0.0.0.0" source_ip = "1.1.1.1/30" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } diff --git a/examples/resources/aci_pim_route_map_policy/resource-all-attributes.tf b/examples/resources/aci_pim_route_map_policy/resource-all-attributes.tf index 76766aaf0..d1fe02c69 100644 --- a/examples/resources/aci_pim_route_map_policy/resource-all-attributes.tf +++ b/examples/resources/aci_pim_route_map_policy/resource-all-attributes.tf @@ -7,16 +7,4 @@ resource "aci_pim_route_map_policy" "full_example_tenant" { name_alias = "name_alias" owner_key = "owner_key" owner_tag = "owner_tag" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } diff --git a/examples/resources/aci_relation_to_consumed_out_of_band_contract/resource-all-attributes.tf b/examples/resources/aci_relation_to_consumed_out_of_band_contract/resource-all-attributes.tf index da51cd5a4..3b9ab8e11 100644 --- a/examples/resources/aci_relation_to_consumed_out_of_band_contract/resource-all-attributes.tf +++ b/examples/resources/aci_relation_to_consumed_out_of_band_contract/resource-all-attributes.tf @@ -4,16 +4,4 @@ resource "aci_relation_to_consumed_out_of_band_contract" "full_example_external_ annotation = "annotation" priority = "level1" out_of_band_contract_name = aci_out_of_band_contract.example.name - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } diff --git a/examples/resources/aci_relation_to_fallback_route_group/resource-all-attributes.tf b/examples/resources/aci_relation_to_fallback_route_group/resource-all-attributes.tf index 34cbde73b..9046e1796 100644 --- a/examples/resources/aci_relation_to_fallback_route_group/resource-all-attributes.tf +++ b/examples/resources/aci_relation_to_fallback_route_group/resource-all-attributes.tf @@ -3,16 +3,4 @@ resource "aci_relation_to_fallback_route_group" "full_example_l3_outside" { parent_dn = aci_l3_outside.example.id annotation = "annotation" target_dn = aci_vrf_fallback_route_group.test.id - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } diff --git a/examples/resources/aci_vrf_fallback_route_group/resource-all-attributes.tf b/examples/resources/aci_vrf_fallback_route_group/resource-all-attributes.tf index b62d8fdf0..27a95bd47 100644 --- a/examples/resources/aci_vrf_fallback_route_group/resource-all-attributes.tf +++ b/examples/resources/aci_vrf_fallback_route_group/resource-all-attributes.tf @@ -14,16 +14,4 @@ resource "aci_vrf_fallback_route_group" "full_example_vrf" { fallback_member = "2.2.2.2" } ] - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } diff --git a/examples/resources/aci_vrf_fallback_route_group_member/resource-all-attributes.tf b/examples/resources/aci_vrf_fallback_route_group_member/resource-all-attributes.tf index bea43151d..77f4de9ac 100644 --- a/examples/resources/aci_vrf_fallback_route_group_member/resource-all-attributes.tf +++ b/examples/resources/aci_vrf_fallback_route_group_member/resource-all-attributes.tf @@ -6,16 +6,4 @@ resource "aci_vrf_fallback_route_group_member" "full_example_vrf_fallback_route_ name = "name" name_alias = "name_alias" fallback_member = "2.2.2.3" - annotations = [ - { - key = "key_0" - value = "value_1" - } - ] - tags = [ - { - key = "key_0" - value = "value_1" - } - ] } diff --git a/gen/definitions/classes.yaml b/gen/definitions/classes.yaml index c7c2deb29..4ee550d71 100644 --- a/gen/definitions/classes.yaml +++ b/gen/definitions/classes.yaml @@ -223,3 +223,16 @@ commPol: contained_by: - "polUni" rn_prepend: "fabric" + children: + - tagAnnotation + - tagTag + +commHttps: + children: + - tagAnnotation + # - tagTag + +# commRsKeyRing: +# children: +# - tagAnnotation + diff --git a/gen/generator.go b/gen/generator.go index 1c706bc3b..fc460ba14 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -112,7 +112,7 @@ var duplicateLabels = []string{} var resourceNames = map[string]string{} var rnPrefix = map[string]string{} var targetRelationalPropertyClasses = map[string]string{} -var alwaysIncludeChildren = []string{"tag:Annotation", "tag:Tag"} +var alwaysIncludeChildren = []string{} var excludeChildResourceNamesFromDocs = []string{"", "annotation", "tag"} func GetResourceNameAsDescription(s string, definitions Definitions) string { diff --git a/gen/templates/resource.go.tmpl b/gen/templates/resource.go.tmpl index 22b517604..86c9bbd5e 100644 --- a/gen/templates/resource.go.tmpl +++ b/gen/templates/resource.go.tmpl @@ -515,8 +515,8 @@ func getAndSet{{.ResourceClassName}}Attributes(ctx context.Context, diags *diag. } } {{- range .Children}} - {{.ResourceClassName}}Set,_:=types.SetValueFrom(ctx,{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModelElementType(),{{.ResourceClassName}}{{.ParentHierarchy}}List) - {{.ParentHierarchy}}.{{.ResourceClassName}}={{.ResourceClassName}}Set + {{.ResourceClassName}}{{.ParentHierarchy}}Set,_:=types.SetValueFrom(ctx,{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModelElementType(),{{.ResourceClassName}}{{.ParentHierarchy}}List) + {{.ParentHierarchy}}.{{.ResourceClassName}}={{.ResourceClassName}}{{.ParentHierarchy}}Set {{- end}} {{- else}} } @@ -594,7 +594,6 @@ func set{{.ResourceClassName}}Id(ctx context.Context, data *{{.ResourceClassName {{ range .Children}} {{- $child:= .}} func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *{{$.ResourceClassName}}ResourceModel, {{.PkgName}}{{.ParentHierarchy}}Plan, {{.PkgName}}{{.ParentHierarchy}}State []{{.ResourceClassName}}{{$.ResourceClassName}}ResourceModel) []map[string]interface{} { - childMap := NewAciObject() childPayloads := []map[string]interface{}{} {{- $enteredGrandChildDeclarationZone := false }} {{- range .Children}} @@ -612,6 +611,7 @@ func get{{$.ResourceClassName}}{{ .ResourceClassName }}ChildPayloads(ctx context {{ .PkgName }}Identifiers := []{{.ResourceClassName}}Identifier{} {{- end}} for _, {{ .PkgName }}{{.ParentHierarchy}} := range {{ .PkgName }}{{.ParentHierarchy}}Plan { + childMap := NewAciObject() {{- range .Properties}} if !{{ .PkgName }}{{$child.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsNull() && !{{ .PkgName }}{{$child.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsUnknown(){ {{- if eq .ValueType "bitmask"}} @@ -862,26 +862,15 @@ func {{.ResourceClassName}}{{.ParentHierarchy}}ResourceModelElementType() attr.T {{/* A sub template for the grand child attributes used in the Payload function. */}} {{- define "grandChildPayload" }} +{{$grandChild:= .}} var {{.PkgName}}{{.ParentHierarchy}}Plan, {{.PkgName}}{{.ParentHierarchy}}State []{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModel {{.ParentHierarchy | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}{{.ParentHierarchy}}Plan, false) -for _, {{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}}State := range {{.ParentHierarchy | lowerFirstCharacter}}State { -{{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}}State.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}{{.ParentHierarchy}}State, false) -if len({{ .PkgName }}{{.ParentHierarchy}}Plan) == 0 && len({{.PkgName}}{{.ParentHierarchy}}State) == 1 { - {{- if .AllowDelete}} - {{.PkgName}}{{.ParentHierarchy}}ChildMap := NewAciObject() - {{.PkgName}}{{.ParentHierarchy}}ChildMap.Attributes["status"] = "deleted" - {{ .ParentHierarchy }}Children = append({{ .ParentHierarchy }}Children, map[string]interface{}{"{{.PkgName}}": {{.PkgName}}{{.ParentHierarchy}}ChildMap}) - {{- else}} - diags.AddError( - "{{ .ResourceClassName }} object cannot be deleted", - "deletion of child is only possible upon deletion of the parent", - ) - return nil - {{- end }} -} -} if !{{ .ParentHierarchy | lowerFirstCharacter}}.{{.ResourceClassName}}.IsNull() && !{{ .ParentHierarchy | lowerFirstCharacter}}.{{.ResourceClassName}}.IsUnknown(){ +{{- if .IdentifiedBy}} + {{ .PkgName }}Identifiers := []{{.ResourceClassName}}Identifier{} +{{- end}} for _, {{ .PkgName }}{{.ParentHierarchy}} := range {{.PkgName}}{{.ParentHierarchy}}Plan { + {{.PkgName}}{{.ParentHierarchy}}ChildMap := NewAciObject() {{- range .Properties}} if !{{ .PkgName }}{{$.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsNull() && !{{ .PkgName }}{{$.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.IsUnknown(){ {{- if eq .ValueType "bitmask"}} @@ -901,8 +890,63 @@ for _, {{ .PkgName }}{{.ParentHierarchy}} := range {{.PkgName}}{{.ParentHierarch {{- template "grandChildPayload" . }} {{- end}} {{ .ParentHierarchy }}Children = append({{ .ParentHierarchy }}Children, map[string]interface{}{"{{.PkgName}}": {{.PkgName}}{{$.ParentHierarchy}}ChildMap}) + {{- if .IdentifiedBy}} + {{ .PkgName }}Identifier := {{ .ResourceClassName }}Identifier{} + {{- range .Properties}} + {{- if .IsNaming}} + {{ .PkgName }}Identifier.{{.Name}} = {{ .PkgName }}{{$grandChild.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}} + {{- end}} + {{- end}} + {{ .PkgName }}Identifiers = append({{ .PkgName }}Identifiers, {{ .PkgName }}Identifier) + {{- end}} + } + {{- if .IdentifiedBy}} + for _, {{ .PkgName }}{{.ParentHierarchy}}state := range {{.ParentHierarchy | lowerFirstCharacter}}State { + {{ .PkgName }}{{.ParentHierarchy}}state.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}{{.ParentHierarchy}}State, false) + for _, {{ .PkgName }}{{.ParentHierarchy}} := range {{ .PkgName }}{{.ParentHierarchy}}State { + delete := true + for _, {{ .PkgName }}Identifier := range {{ .PkgName }}Identifiers { {{$i := 1}}{{$length := len .IdentifiedBy}} + if + {{- range .Properties}} + {{- if .IsNaming }} + {{ .PkgName }}Identifier.{{.Name}} == {{ .PkgName }}{{$grandChild.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}{{- if ne $length $i}} {{$i = add $i 1}} && {{- end}} + {{- end}} + {{- end}} { + delete = false + break + } + } + if delete { + {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete := NewAciObject() + {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete.Attributes["status"] = "deleted" + {{- range .Properties}} + {{- if .IsNaming }} + {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete.Attributes["{{.PropertyName}}"] = {{ .PkgName }}{{$grandChild.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.ValueString() + {{- end}} + {{- end}} + {{ .ParentHierarchy }}Children = append({{ .ParentHierarchy }}Children, map[string]interface{}{"{{ .PkgName }}": {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete}) + } + } + } + {{- else}} + for _, {{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}}State := range {{.ParentHierarchy | lowerFirstCharacter}}State { + {{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}}State.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}{{.ParentHierarchy}}State, false) + if len({{ .PkgName }}{{.ParentHierarchy}}Plan) == 0 && len({{.PkgName}}{{.ParentHierarchy}}State) == 1 { + {{- if .AllowDelete}} + {{.PkgName}}{{.ParentHierarchy}}ChildMap := NewAciObject() + {{.PkgName}}{{.ParentHierarchy}}ChildMap.Attributes["status"] = "deleted" + {{ .ParentHierarchy }}Children = append({{ .ParentHierarchy }}Children, map[string]interface{}{"{{.PkgName}}": {{.PkgName}}{{.ParentHierarchy}}ChildMap}) + {{- else}} + diags.AddError( + "{{ .ResourceClassName }} object cannot be deleted", + "deletion of child is only possible upon deletion of the parent", + ) + return nil + {{- end }} + } + } + {{- end }} } - } {{- end }} @@ -982,8 +1026,8 @@ for childAttributeName, childAttributeValue := range {{.PkgName}}childAttributeV } } {{- range .Children}} - {{.ResourceClassName}}Set,_:=types.SetValueFrom(ctx,{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModelElementType(),{{.ResourceClassName}}{{.ParentHierarchy}}List) - {{.ParentHierarchy}}.{{.ResourceClassName}}={{.ResourceClassName}}Set + {{.ResourceClassName}}{{.ParentHierarchy}}Set,_:=types.SetValueFrom(ctx,{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModelElementType(),{{.ResourceClassName}}{{.ParentHierarchy}}List) + {{.ParentHierarchy}}.{{.ResourceClassName}}={{.ResourceClassName}}{{.ParentHierarchy}}Set {{- end}} {{- else}} } @@ -995,7 +1039,6 @@ for childAttributeName, childAttributeValue := range {{.PkgName}}childAttributeV {{/* A sub template for grand child declaration in the child payload function. */}} {{- define "grandChildDeclarationInChildPayloadFunction" }} -{{.PkgName}}{{.ParentHierarchy}}ChildMap := NewAciObject() {{- $enteredGrandChildDeclarationZone := false }} {{- range .Children}} {{- $enteredGrandChildDeclarationZone = true }} diff --git a/gen/testvars/fvEpIpTag.yaml b/gen/testvars/fvEpIpTag.yaml index 07b6c2485..6d855ede7 100644 --- a/gen/testvars/fvEpIpTag.yaml +++ b/gen/testvars/fvEpIpTag.yaml @@ -26,21 +26,6 @@ all: name: "name" name_alias: "name_alias" -children: - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - parents: - class_name: "fvTenant" parent_dependency: "" diff --git a/gen/testvars/fvEpMacTag.yaml b/gen/testvars/fvEpMacTag.yaml index 5c4298d7f..6afbe9ad1 100644 --- a/gen/testvars/fvEpMacTag.yaml +++ b/gen/testvars/fvEpMacTag.yaml @@ -26,21 +26,6 @@ all: name: "name" name_alias: "name_alias" -children: - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - parents: - class_name: "fvTenant" parent_dependency: "" diff --git a/gen/testvars/fvFBRGroup.yaml b/gen/testvars/fvFBRGroup.yaml index 8fd06febd..e6c0860b3 100644 --- a/gen/testvars/fvFBRGroup.yaml +++ b/gen/testvars/fvFBRGroup.yaml @@ -35,20 +35,6 @@ children: name_alias: "name_alias_2" fallback_member: "2.2.2.3" - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - parents: - class_name: "fvCtx" parent_dependency: "fvTenant" diff --git a/gen/testvars/fvFBRMember.yaml b/gen/testvars/fvFBRMember.yaml index 218e652f2..34ab51313 100644 --- a/gen/testvars/fvFBRMember.yaml +++ b/gen/testvars/fvFBRMember.yaml @@ -23,21 +23,6 @@ all: name: "name" name_alias: "name_alias" -children: - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - parents: - class_name: "fvFBRGroup" parent_dependency: "fvCtx" diff --git a/gen/testvars/l3extConsLbl.yaml b/gen/testvars/l3extConsLbl.yaml index fabbd89ac..e32d8d4c1 100644 --- a/gen/testvars/l3extConsLbl.yaml +++ b/gen/testvars/l3extConsLbl.yaml @@ -29,21 +29,6 @@ all: owner_tag: "owner_tag" tag: "lemon-chiffon" -children: - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - parents: - class_name: "l3extOut" parent_dependency: "" diff --git a/gen/testvars/l3extRsOutToFBRGroup.yaml b/gen/testvars/l3extRsOutToFBRGroup.yaml index 12a6716b9..4f2bfd547 100644 --- a/gen/testvars/l3extRsOutToFBRGroup.yaml +++ b/gen/testvars/l3extRsOutToFBRGroup.yaml @@ -17,21 +17,6 @@ resource_required: all: annotation: "annotation" -children: - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - parents: - class_name: "l3extOut" parent_dependency: "fvTenant" diff --git a/gen/testvars/l3extRsRedistributePol.yaml b/gen/testvars/l3extRsRedistributePol.yaml index fcd38f5b5..f13c9c2c3 100644 --- a/gen/testvars/l3extRsRedistributePol.yaml +++ b/gen/testvars/l3extRsRedistributePol.yaml @@ -22,21 +22,6 @@ all: annotation: "annotation" source: "direct" -children: - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - parents: - class_name: "l3extOut" parent_dependency: "fvTenant" diff --git a/gen/testvars/mgmtInstP.yaml b/gen/testvars/mgmtInstP.yaml index a2c1874a2..7c915eaea 100644 --- a/gen/testvars/mgmtInstP.yaml +++ b/gen/testvars/mgmtInstP.yaml @@ -33,17 +33,3 @@ children: priority: "level2" out_of_band_contract_name: "out_of_band_contract_name_1" - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - diff --git a/gen/testvars/mgmtRsOoBCons.yaml b/gen/testvars/mgmtRsOoBCons.yaml index 301687bba..ff08401f0 100644 --- a/gen/testvars/mgmtRsOoBCons.yaml +++ b/gen/testvars/mgmtRsOoBCons.yaml @@ -19,21 +19,6 @@ all: annotation: "annotation" priority: "level1" -children: - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - parents: - class_name: "mgmtInstP" parent_dependency: "" diff --git a/gen/testvars/mgmtSubnet.yaml b/gen/testvars/mgmtSubnet.yaml index b7280633a..b37e5a836 100644 --- a/gen/testvars/mgmtSubnet.yaml +++ b/gen/testvars/mgmtSubnet.yaml @@ -23,21 +23,6 @@ all: name: "name" name_alias: "name_alias" -children: - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - parents: - class_name: "mgmtInstP" parent_dependency: "" diff --git a/gen/testvars/pimRouteMapEntry.yaml b/gen/testvars/pimRouteMapEntry.yaml index bfdfb090d..7b5ea9d43 100644 --- a/gen/testvars/pimRouteMapEntry.yaml +++ b/gen/testvars/pimRouteMapEntry.yaml @@ -31,21 +31,6 @@ all: rendezvous_point_ip: "0.0.0.0" source_ip: "1.1.1.1/30" -children: - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - parents: - class_name: "pimRouteMapPol" parent_dependency: "fvTenant" diff --git a/gen/testvars/pimRouteMapPol.yaml b/gen/testvars/pimRouteMapPol.yaml index cac7fd60c..51d708005 100644 --- a/gen/testvars/pimRouteMapPol.yaml +++ b/gen/testvars/pimRouteMapPol.yaml @@ -25,21 +25,6 @@ all: owner_key: "owner_key" owner_tag: "owner_tag" -children: - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - parents: - class_name: "fvTenant" parent_dependency: "" diff --git a/gen/testvars/vzOOBBrCP.yaml b/gen/testvars/vzOOBBrCP.yaml index 2c6696909..418042e4e 100644 --- a/gen/testvars/vzOOBBrCP.yaml +++ b/gen/testvars/vzOOBBrCP.yaml @@ -33,18 +33,3 @@ all: scope: "application-profile" target_dscp: "AF11" -children: - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - diff --git a/internal/provider/data_source_aci_endpoint_tag_ip.go b/internal/provider/data_source_aci_endpoint_tag_ip.go index 7c1bf4a91..814d8978a 100644 --- a/internal/provider/data_source_aci_endpoint_tag_ip.go +++ b/internal/provider/data_source_aci_endpoint_tag_ip.go @@ -72,38 +72,6 @@ func (d *FvEpIpTagDataSource) Schema(ctx context.Context, req datasource.SchemaR Computed: true, MarkdownDescription: `The name alias of the Endpoint Tag Ip object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of datasource: aci_endpoint_tag_ip") diff --git a/internal/provider/data_source_aci_endpoint_tag_mac.go b/internal/provider/data_source_aci_endpoint_tag_mac.go index 20681e3c3..2395357de 100644 --- a/internal/provider/data_source_aci_endpoint_tag_mac.go +++ b/internal/provider/data_source_aci_endpoint_tag_mac.go @@ -72,38 +72,6 @@ func (d *FvEpMacTagDataSource) Schema(ctx context.Context, req datasource.Schema Computed: true, MarkdownDescription: `The name alias of the Endpoint Tag Mac object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of datasource: aci_endpoint_tag_mac") diff --git a/internal/provider/data_source_aci_external_management_network_instance_profile.go b/internal/provider/data_source_aci_external_management_network_instance_profile.go index 4c1859580..dc75b8340 100644 --- a/internal/provider/data_source_aci_external_management_network_instance_profile.go +++ b/internal/provider/data_source_aci_external_management_network_instance_profile.go @@ -84,38 +84,6 @@ func (d *MgmtInstPDataSource) Schema(ctx context.Context, req datasource.SchemaR }, }, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of datasource: aci_external_management_network_instance_profile") diff --git a/internal/provider/data_source_aci_external_management_network_subnet.go b/internal/provider/data_source_aci_external_management_network_subnet.go index c14f87be2..0edf2a502 100644 --- a/internal/provider/data_source_aci_external_management_network_subnet.go +++ b/internal/provider/data_source_aci_external_management_network_subnet.go @@ -68,38 +68,6 @@ func (d *MgmtSubnetDataSource) Schema(ctx context.Context, req datasource.Schema Computed: true, MarkdownDescription: `The name alias of the External Management Network Subnet object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of datasource: aci_external_management_network_subnet") diff --git a/internal/provider/data_source_aci_l3out_consumer_label.go b/internal/provider/data_source_aci_l3out_consumer_label.go index 8781de9e8..64baf147a 100644 --- a/internal/provider/data_source_aci_l3out_consumer_label.go +++ b/internal/provider/data_source_aci_l3out_consumer_label.go @@ -80,38 +80,6 @@ func (d *L3extConsLblDataSource) Schema(ctx context.Context, req datasource.Sche Computed: true, MarkdownDescription: `Specifies the color of a policy label.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of datasource: aci_l3out_consumer_label") diff --git a/internal/provider/data_source_aci_l3out_redistribute_policy.go b/internal/provider/data_source_aci_l3out_redistribute_policy.go index 63f2003f1..2c72a39c1 100644 --- a/internal/provider/data_source_aci_l3out_redistribute_policy.go +++ b/internal/provider/data_source_aci_l3out_redistribute_policy.go @@ -60,38 +60,6 @@ func (d *L3extRsRedistributePolDataSource) Schema(ctx context.Context, req datas Required: true, MarkdownDescription: `The name of the Route Control Profile object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of datasource: aci_l3out_redistribute_policy") diff --git a/internal/provider/data_source_aci_out_of_band_contract.go b/internal/provider/data_source_aci_out_of_band_contract.go index 28c567b69..bb5a9f0f3 100644 --- a/internal/provider/data_source_aci_out_of_band_contract.go +++ b/internal/provider/data_source_aci_out_of_band_contract.go @@ -84,38 +84,6 @@ func (d *VzOOBBrCPDataSource) Schema(ctx context.Context, req datasource.SchemaR Computed: true, MarkdownDescription: `The target DSCP value of the Out Of Band Contract object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of datasource: aci_out_of_band_contract") diff --git a/internal/provider/data_source_aci_pim_route_map_entry.go b/internal/provider/data_source_aci_pim_route_map_entry.go index 4df1c989f..b438d7853 100644 --- a/internal/provider/data_source_aci_pim_route_map_entry.go +++ b/internal/provider/data_source_aci_pim_route_map_entry.go @@ -84,38 +84,6 @@ func (d *PimRouteMapEntryDataSource) Schema(ctx context.Context, req datasource. Computed: true, MarkdownDescription: `The source ip of the Pim Route Map Entry object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of datasource: aci_pim_route_map_entry") diff --git a/internal/provider/data_source_aci_pim_route_map_policy.go b/internal/provider/data_source_aci_pim_route_map_policy.go index 4959e5239..2227e0c4a 100644 --- a/internal/provider/data_source_aci_pim_route_map_policy.go +++ b/internal/provider/data_source_aci_pim_route_map_policy.go @@ -72,38 +72,6 @@ func (d *PimRouteMapPolDataSource) Schema(ctx context.Context, req datasource.Sc Computed: true, MarkdownDescription: `A tag for enabling clients to add their own data. For example, to indicate who created this object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of datasource: aci_pim_route_map_policy") diff --git a/internal/provider/data_source_aci_relation_to_consumed_out_of_band_contract.go b/internal/provider/data_source_aci_relation_to_consumed_out_of_band_contract.go index 3a1f25c2e..92d8a8d4c 100644 --- a/internal/provider/data_source_aci_relation_to_consumed_out_of_band_contract.go +++ b/internal/provider/data_source_aci_relation_to_consumed_out_of_band_contract.go @@ -60,38 +60,6 @@ func (d *MgmtRsOoBConsDataSource) Schema(ctx context.Context, req datasource.Sch Required: true, MarkdownDescription: `The name of the Out Of Band Contract object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of datasource: aci_relation_to_consumed_out_of_band_contract") diff --git a/internal/provider/data_source_aci_relation_to_fallback_route_group.go b/internal/provider/data_source_aci_relation_to_fallback_route_group.go index 43ff1992b..b84193cb0 100644 --- a/internal/provider/data_source_aci_relation_to_fallback_route_group.go +++ b/internal/provider/data_source_aci_relation_to_fallback_route_group.go @@ -56,38 +56,6 @@ func (d *L3extRsOutToFBRGroupDataSource) Schema(ctx context.Context, req datasou Required: true, MarkdownDescription: `The distinguished name of the VRF Fallback Route Group object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of datasource: aci_relation_to_fallback_route_group") diff --git a/internal/provider/data_source_aci_vrf_fallback_route_group.go b/internal/provider/data_source_aci_vrf_fallback_route_group.go index 25948dd50..dee8baa03 100644 --- a/internal/provider/data_source_aci_vrf_fallback_route_group.go +++ b/internal/provider/data_source_aci_vrf_fallback_route_group.go @@ -92,38 +92,6 @@ func (d *FvFBRGroupDataSource) Schema(ctx context.Context, req datasource.Schema }, }, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of datasource: aci_vrf_fallback_route_group") diff --git a/internal/provider/data_source_aci_vrf_fallback_route_group_member.go b/internal/provider/data_source_aci_vrf_fallback_route_group_member.go index 11bc2a747..8cee4b87b 100644 --- a/internal/provider/data_source_aci_vrf_fallback_route_group_member.go +++ b/internal/provider/data_source_aci_vrf_fallback_route_group_member.go @@ -68,38 +68,6 @@ func (d *FvFBRMemberDataSource) Schema(ctx context.Context, req datasource.Schem Required: true, MarkdownDescription: `The address of the VRF Fallback Route Group Member object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Computed: true, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of datasource: aci_vrf_fallback_route_group_member") diff --git a/internal/provider/resource_aci_communication_policy.go b/internal/provider/resource_aci_communication_policy.go index c25c84987..eed1eaaee 100644 --- a/internal/provider/resource_aci_communication_policy.go +++ b/internal/provider/resource_aci_communication_policy.go @@ -85,7 +85,6 @@ type CommHttpsCommPolResourceModel struct { CommRsClientCertCA types.Set `tfsdk:"tp"` CommRsKeyRing types.Set `tfsdk:"key_ring"` TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` } func CommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { @@ -115,7 +114,6 @@ func CommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { "tp": types.SetType{ElemType: types.StringType}, "key_ring": types.SetType{ElemType: types.StringType}, "annotations": types.SetType{ElemType: types.StringType}, - "tags": types.SetType{ElemType: types.StringType}, } } @@ -125,18 +123,14 @@ func CommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { // CommRsClientCertCACommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. type CommRsClientCertCACommHttpsCommPolResourceModel struct { - Annotation types.String `tfsdk:"annotation"` - TDn types.String `tfsdk:"target_dn"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` + Annotation types.String `tfsdk:"annotation"` + TDn types.String `tfsdk:"target_dn"` } func CommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { return map[string]attr.Type{ - "annotation": types.StringType, - "target_dn": types.StringType, - "annotations": types.SetType{ElemType: types.StringType}, - "tags": types.SetType{ElemType: types.StringType}, + "annotation": types.StringType, + "target_dn": types.StringType, } } @@ -144,54 +138,16 @@ func CommRsClientCertCACommHttpsCommPolResourceModelElementType() attr.TypeWithA return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes()) } -// TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes()) -} - -// TagTagCommRsClientCertCACommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. -type TagTagCommRsClientCertCACommHttpsCommPolResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagCommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagCommRsClientCertCACommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagCommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes()) -} - // CommRsKeyRingCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. type CommRsKeyRingCommHttpsCommPolResourceModel struct { Annotation types.String `tfsdk:"annotation"` TnPkiKeyRingName types.String `tfsdk:"tn_pki_key_ring_name"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` } func CommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { return map[string]attr.Type{ "annotation": types.StringType, "tn_pki_key_ring_name": types.StringType, - "annotations": types.SetType{ElemType: types.StringType}, - "tags": types.SetType{ElemType: types.StringType}, } } @@ -199,40 +155,6 @@ func CommRsKeyRingCommHttpsCommPolResourceModelElementType() attr.TypeWithAttrib return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes()) } -// TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes()) -} - -// TagTagCommRsKeyRingCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. -type TagTagCommRsKeyRingCommHttpsCommPolResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagCommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagCommRsKeyRingCommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagCommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes()) -} - // TagAnnotationCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. type TagAnnotationCommHttpsCommPolResourceModel struct { Key types.String `tfsdk:"key"` @@ -250,23 +172,6 @@ func TagAnnotationCommHttpsCommPolResourceModelElementType() attr.TypeWithAttrib return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationCommHttpsCommPolResourceModelAttributeTypes()) } -// TagTagCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. -type TagTagCommHttpsCommPolResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagCommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagCommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagCommHttpsCommPolResourceModelAttributeTypes()) -} - // TagAnnotationCommPolResourceModel describes the resource data model for the children without relation ships. type TagAnnotationCommPolResourceModel struct { Key types.String `tfsdk:"key"` @@ -668,62 +573,6 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest }, MarkdownDescription: `The distinguished name of the target.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, }, }, @@ -757,62 +606,6 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest }, MarkdownDescription: `The HTTP connection key ring. Each PKI device holds a pair of asymmetric Rivest-Shamir-Adleman (RSA) or Elliptic Curve Cryptography (ECC) encryption keys, one kept private and one made public, stored in an internal key ring.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, }, }, @@ -844,34 +637,6 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest }, }, }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, }, }, @@ -1110,7 +875,7 @@ func (r *CommPolResource) ImportState(ctx context.Context, req resource.ImportSt } func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *CommPolResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "commPol,commHttps,tagAnnotation,tagTag,commRsClientCertCA,commRsKeyRing,tagAnnotation,tagTag,tagAnnotation,tagTag,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "commPol,commHttps,tagAnnotation,tagTag,commRsClientCertCA,commRsKeyRing,tagAnnotation"), "GET", nil) if diags.HasError() { return @@ -1170,20 +935,10 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl CommHttpsCommPolList := make([]CommHttpsCommPolResourceModel, 0) CommRsClientCertCACommHttpsCommPol := CommRsClientCertCACommHttpsCommPolResourceModel{} CommRsClientCertCACommHttpsCommPolList := make([]CommRsClientCertCACommHttpsCommPolResourceModel, 0) - TagAnnotationCommRsClientCertCACommHttpsCommPol := TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel{} - TagAnnotationCommRsClientCertCACommHttpsCommPolList := make([]TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel, 0) - TagTagCommRsClientCertCACommHttpsCommPol := TagTagCommRsClientCertCACommHttpsCommPolResourceModel{} - TagTagCommRsClientCertCACommHttpsCommPolList := make([]TagTagCommRsClientCertCACommHttpsCommPolResourceModel, 0) CommRsKeyRingCommHttpsCommPol := CommRsKeyRingCommHttpsCommPolResourceModel{} CommRsKeyRingCommHttpsCommPolList := make([]CommRsKeyRingCommHttpsCommPolResourceModel, 0) - TagAnnotationCommRsKeyRingCommHttpsCommPol := TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel{} - TagAnnotationCommRsKeyRingCommHttpsCommPolList := make([]TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel, 0) - TagTagCommRsKeyRingCommHttpsCommPol := TagTagCommRsKeyRingCommHttpsCommPolResourceModel{} - TagTagCommRsKeyRingCommHttpsCommPolList := make([]TagTagCommRsKeyRingCommHttpsCommPolResourceModel, 0) TagAnnotationCommHttpsCommPol := TagAnnotationCommHttpsCommPolResourceModel{} TagAnnotationCommHttpsCommPolList := make([]TagAnnotationCommHttpsCommPolResourceModel, 0) - TagTagCommHttpsCommPol := TagTagCommHttpsCommPolResourceModel{} - TagTagCommHttpsCommPolList := make([]TagTagCommHttpsCommPolResourceModel, 0) TagAnnotationCommPol := TagAnnotationCommPolResourceModel{} TagAnnotationCommPolList := make([]TagAnnotationCommPolResourceModel, 0) TagTagCommPol := TagTagCommPolResourceModel{} @@ -1283,41 +1038,6 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl CommRsClientCertCACommHttpsCommPol.TDn = basetypes.NewStringValue(childAttributeValue.(string)) } } - childrenOfCommRsClientCertCACommHttpsCommPol, childrenOfCommRsClientCertCACommHttpsCommPolExist := childClassDetailsCommHttpsCommPol.(map[string]interface{})["children"] - if childrenOfCommRsClientCertCACommHttpsCommPolExist { - for _, childCommRsClientCertCACommHttpsCommPol := range childrenOfCommRsClientCertCACommHttpsCommPol.([]interface{}) { - for childClassNameCommRsClientCertCACommHttpsCommPol, childClassDetailsCommRsClientCertCACommHttpsCommPol := range childCommRsClientCertCACommHttpsCommPol.(map[string]interface{}) { - if childClassNameCommRsClientCertCACommHttpsCommPol == "tagAnnotation" { - tagAnnotationchildAttributeValue := childClassDetailsCommRsClientCertCACommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) - for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { - if childAttributeName == "key" { - TagAnnotationCommRsClientCertCACommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationCommRsClientCertCACommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - } - TagAnnotationCommRsClientCertCACommHttpsCommPolList = append(TagAnnotationCommRsClientCertCACommHttpsCommPolList, TagAnnotationCommRsClientCertCACommHttpsCommPol) - } - if childClassNameCommRsClientCertCACommHttpsCommPol == "tagTag" { - tagTagchildAttributeValue := childClassDetailsCommRsClientCertCACommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) - for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { - if childAttributeName == "key" { - TagTagCommRsClientCertCACommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagCommRsClientCertCACommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - } - TagTagCommRsClientCertCACommHttpsCommPolList = append(TagTagCommRsClientCertCACommHttpsCommPolList, TagTagCommRsClientCertCACommHttpsCommPol) - } - } - } - } - TagAnnotationSet, _ := types.SetValueFrom(ctx, TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModelElementType(), TagAnnotationCommRsClientCertCACommHttpsCommPolList) - CommRsClientCertCACommHttpsCommPol.TagAnnotation = TagAnnotationSet - TagTagSet, _ := types.SetValueFrom(ctx, TagTagCommRsClientCertCACommHttpsCommPolResourceModelElementType(), TagTagCommRsClientCertCACommHttpsCommPolList) - CommRsClientCertCACommHttpsCommPol.TagTag = TagTagSet CommRsClientCertCACommHttpsCommPolList = append(CommRsClientCertCACommHttpsCommPolList, CommRsClientCertCACommHttpsCommPol) } if childClassNameCommHttpsCommPol == "commRsKeyRing" { @@ -1330,41 +1050,6 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl CommRsKeyRingCommHttpsCommPol.TnPkiKeyRingName = basetypes.NewStringValue(childAttributeValue.(string)) } } - childrenOfCommRsKeyRingCommHttpsCommPol, childrenOfCommRsKeyRingCommHttpsCommPolExist := childClassDetailsCommHttpsCommPol.(map[string]interface{})["children"] - if childrenOfCommRsKeyRingCommHttpsCommPolExist { - for _, childCommRsKeyRingCommHttpsCommPol := range childrenOfCommRsKeyRingCommHttpsCommPol.([]interface{}) { - for childClassNameCommRsKeyRingCommHttpsCommPol, childClassDetailsCommRsKeyRingCommHttpsCommPol := range childCommRsKeyRingCommHttpsCommPol.(map[string]interface{}) { - if childClassNameCommRsKeyRingCommHttpsCommPol == "tagAnnotation" { - tagAnnotationchildAttributeValue := childClassDetailsCommRsKeyRingCommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) - for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { - if childAttributeName == "key" { - TagAnnotationCommRsKeyRingCommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationCommRsKeyRingCommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - } - TagAnnotationCommRsKeyRingCommHttpsCommPolList = append(TagAnnotationCommRsKeyRingCommHttpsCommPolList, TagAnnotationCommRsKeyRingCommHttpsCommPol) - } - if childClassNameCommRsKeyRingCommHttpsCommPol == "tagTag" { - tagTagchildAttributeValue := childClassDetailsCommRsKeyRingCommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) - for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { - if childAttributeName == "key" { - TagTagCommRsKeyRingCommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagCommRsKeyRingCommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - } - TagTagCommRsKeyRingCommHttpsCommPolList = append(TagTagCommRsKeyRingCommHttpsCommPolList, TagTagCommRsKeyRingCommHttpsCommPol) - } - } - } - } - TagAnnotationSet, _ := types.SetValueFrom(ctx, TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModelElementType(), TagAnnotationCommRsKeyRingCommHttpsCommPolList) - CommRsKeyRingCommHttpsCommPol.TagAnnotation = TagAnnotationSet - TagTagSet, _ := types.SetValueFrom(ctx, TagTagCommRsKeyRingCommHttpsCommPolResourceModelElementType(), TagTagCommRsKeyRingCommHttpsCommPolList) - CommRsKeyRingCommHttpsCommPol.TagTag = TagTagSet CommRsKeyRingCommHttpsCommPolList = append(CommRsKeyRingCommHttpsCommPolList, CommRsKeyRingCommHttpsCommPol) } if childClassNameCommHttpsCommPol == "tagAnnotation" { @@ -1379,29 +1064,15 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl } TagAnnotationCommHttpsCommPolList = append(TagAnnotationCommHttpsCommPolList, TagAnnotationCommHttpsCommPol) } - if childClassNameCommHttpsCommPol == "tagTag" { - tagTagchildAttributeValue := childClassDetailsCommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) - for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { - if childAttributeName == "key" { - TagTagCommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagCommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - } - TagTagCommHttpsCommPolList = append(TagTagCommHttpsCommPolList, TagTagCommHttpsCommPol) - } } } } - CommRsClientCertCASet, _ := types.SetValueFrom(ctx, CommRsClientCertCACommHttpsCommPolResourceModelElementType(), CommRsClientCertCACommHttpsCommPolList) - CommHttpsCommPol.CommRsClientCertCA = CommRsClientCertCASet - CommRsKeyRingSet, _ := types.SetValueFrom(ctx, CommRsKeyRingCommHttpsCommPolResourceModelElementType(), CommRsKeyRingCommHttpsCommPolList) - CommHttpsCommPol.CommRsKeyRing = CommRsKeyRingSet - TagAnnotationSet, _ := types.SetValueFrom(ctx, TagAnnotationCommHttpsCommPolResourceModelElementType(), TagAnnotationCommHttpsCommPolList) - CommHttpsCommPol.TagAnnotation = TagAnnotationSet - TagTagSet, _ := types.SetValueFrom(ctx, TagTagCommHttpsCommPolResourceModelElementType(), TagTagCommHttpsCommPolList) - CommHttpsCommPol.TagTag = TagTagSet + CommRsClientCertCACommHttpsCommPolSet, _ := types.SetValueFrom(ctx, CommRsClientCertCACommHttpsCommPolResourceModelElementType(), CommRsClientCertCACommHttpsCommPolList) + CommHttpsCommPol.CommRsClientCertCA = CommRsClientCertCACommHttpsCommPolSet + CommRsKeyRingCommHttpsCommPolSet, _ := types.SetValueFrom(ctx, CommRsKeyRingCommHttpsCommPolResourceModelElementType(), CommRsKeyRingCommHttpsCommPolList) + CommHttpsCommPol.CommRsKeyRing = CommRsKeyRingCommHttpsCommPolSet + TagAnnotationCommHttpsCommPolSet, _ := types.SetValueFrom(ctx, TagAnnotationCommHttpsCommPolResourceModelElementType(), TagAnnotationCommHttpsCommPolList) + CommHttpsCommPol.TagAnnotation = TagAnnotationCommHttpsCommPolSet CommHttpsCommPolList = append(CommHttpsCommPolList, CommHttpsCommPol) } if childClassName == "tagAnnotation" { @@ -1464,21 +1135,11 @@ func setCommPolId(ctx context.Context, data *CommPolResourceModel) { } func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, commHttpsCommPolPlan, commHttpsCommPolState []CommHttpsCommPolResourceModel) []map[string]interface{} { - childMap := NewAciObject() childPayloads := []map[string]interface{}{} - commRsClientCertCACommHttpsCommPolChildMap := NewAciObject() - tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap := NewAciObject() - tagTagCommRsClientCertCACommHttpsCommPolChildMap := NewAciObject() - CommRsClientCertCACommHttpsCommPolChildren := make([]map[string]interface{}, 0) - commRsKeyRingCommHttpsCommPolChildMap := NewAciObject() - tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap := NewAciObject() - tagTagCommRsKeyRingCommHttpsCommPolChildMap := NewAciObject() - CommRsKeyRingCommHttpsCommPolChildren := make([]map[string]interface{}, 0) - tagAnnotationCommHttpsCommPolChildMap := NewAciObject() - tagTagCommHttpsCommPolChildMap := NewAciObject() CommHttpsCommPolChildren := make([]map[string]interface{}, 0) if !data.CommHttps.IsNull() && !data.CommHttps.IsUnknown() { for _, commHttpsCommPol := range commHttpsCommPolPlan { + childMap := NewAciObject() if !commHttpsCommPol.AccessControlAllowCredential.IsNull() && !commHttpsCommPol.AccessControlAllowCredential.IsUnknown() { childMap.Attributes["accessControlAllowCredential"] = commHttpsCommPol.AccessControlAllowCredential.ValueString() } @@ -1549,18 +1210,12 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti if !commHttpsCommPol.VisoreAccess.IsNull() && !commHttpsCommPol.VisoreAccess.IsUnknown() { childMap.Attributes["visoreAccess"] = commHttpsCommPol.VisoreAccess.ValueString() } + var commRsClientCertCACommHttpsCommPolPlan, commRsClientCertCACommHttpsCommPolState []CommRsClientCertCACommHttpsCommPolResourceModel commHttpsCommPol.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCACommHttpsCommPolPlan, false) - for _, commHttpscommRsClientCertCAState := range commHttpsCommPolState { - commHttpscommRsClientCertCAState.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCACommHttpsCommPolState, false) - if len(commRsClientCertCACommHttpsCommPolPlan) == 0 && len(commRsClientCertCACommHttpsCommPolState) == 1 { - commRsClientCertCACommHttpsCommPolChildMap := NewAciObject() - commRsClientCertCACommHttpsCommPolChildMap.Attributes["status"] = "deleted" - CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCACommHttpsCommPolChildMap}) - } - } if !commHttpsCommPol.CommRsClientCertCA.IsNull() && !commHttpsCommPol.CommRsClientCertCA.IsUnknown() { for _, commRsClientCertCACommHttpsCommPol := range commRsClientCertCACommHttpsCommPolPlan { + commRsClientCertCACommHttpsCommPolChildMap := NewAciObject() if !commRsClientCertCACommHttpsCommPol.Annotation.IsNull() && !commRsClientCertCACommHttpsCommPol.Annotation.IsUnknown() { commRsClientCertCACommHttpsCommPolChildMap.Attributes["annotation"] = commRsClientCertCACommHttpsCommPol.Annotation.ValueString() } else { @@ -1569,65 +1224,23 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti if !commRsClientCertCACommHttpsCommPol.TDn.IsNull() && !commRsClientCertCACommHttpsCommPol.TDn.IsUnknown() { commRsClientCertCACommHttpsCommPolChildMap.Attributes["tDn"] = commRsClientCertCACommHttpsCommPol.TDn.ValueString() } - var tagAnnotationCommRsClientCertCACommHttpsCommPolPlan, tagAnnotationCommRsClientCertCACommHttpsCommPolState []TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel - commRsClientCertCACommHttpsCommPol.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommRsClientCertCACommHttpsCommPolPlan, false) - for _, commRsClientCertCAtagAnnotationState := range commRsClientCertCACommHttpsCommPolState { - commRsClientCertCAtagAnnotationState.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommRsClientCertCACommHttpsCommPolState, false) - if len(tagAnnotationCommRsClientCertCACommHttpsCommPolPlan) == 0 && len(tagAnnotationCommRsClientCertCACommHttpsCommPolState) == 1 { - tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap := NewAciObject() - tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap.Attributes["status"] = "deleted" - CommRsClientCertCACommHttpsCommPolChildren = append(CommRsClientCertCACommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap}) - } - } - if !commRsClientCertCACommHttpsCommPol.TagAnnotation.IsNull() && !commRsClientCertCACommHttpsCommPol.TagAnnotation.IsUnknown() { - for _, tagAnnotationCommRsClientCertCACommHttpsCommPol := range tagAnnotationCommRsClientCertCACommHttpsCommPolPlan { - if !tagAnnotationCommRsClientCertCACommHttpsCommPol.Key.IsNull() && !tagAnnotationCommRsClientCertCACommHttpsCommPol.Key.IsUnknown() { - tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap.Attributes["key"] = tagAnnotationCommRsClientCertCACommHttpsCommPol.Key.ValueString() - } - if !tagAnnotationCommRsClientCertCACommHttpsCommPol.Value.IsNull() && !tagAnnotationCommRsClientCertCACommHttpsCommPol.Value.IsUnknown() { - tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap.Attributes["value"] = tagAnnotationCommRsClientCertCACommHttpsCommPol.Value.ValueString() - } - CommRsClientCertCACommHttpsCommPolChildren = append(CommRsClientCertCACommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap}) - } - } - var tagTagCommRsClientCertCACommHttpsCommPolPlan, tagTagCommRsClientCertCACommHttpsCommPolState []TagTagCommRsClientCertCACommHttpsCommPolResourceModel - commRsClientCertCACommHttpsCommPol.TagTag.ElementsAs(ctx, &tagTagCommRsClientCertCACommHttpsCommPolPlan, false) - for _, commRsClientCertCAtagTagState := range commRsClientCertCACommHttpsCommPolState { - commRsClientCertCAtagTagState.TagTag.ElementsAs(ctx, &tagTagCommRsClientCertCACommHttpsCommPolState, false) - if len(tagTagCommRsClientCertCACommHttpsCommPolPlan) == 0 && len(tagTagCommRsClientCertCACommHttpsCommPolState) == 1 { - tagTagCommRsClientCertCACommHttpsCommPolChildMap := NewAciObject() - tagTagCommRsClientCertCACommHttpsCommPolChildMap.Attributes["status"] = "deleted" - CommRsClientCertCACommHttpsCommPolChildren = append(CommRsClientCertCACommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommRsClientCertCACommHttpsCommPolChildMap}) - } - } - if !commRsClientCertCACommHttpsCommPol.TagTag.IsNull() && !commRsClientCertCACommHttpsCommPol.TagTag.IsUnknown() { - for _, tagTagCommRsClientCertCACommHttpsCommPol := range tagTagCommRsClientCertCACommHttpsCommPolPlan { - if !tagTagCommRsClientCertCACommHttpsCommPol.Key.IsNull() && !tagTagCommRsClientCertCACommHttpsCommPol.Key.IsUnknown() { - tagTagCommRsClientCertCACommHttpsCommPolChildMap.Attributes["key"] = tagTagCommRsClientCertCACommHttpsCommPol.Key.ValueString() - } - if !tagTagCommRsClientCertCACommHttpsCommPol.Value.IsNull() && !tagTagCommRsClientCertCACommHttpsCommPol.Value.IsUnknown() { - tagTagCommRsClientCertCACommHttpsCommPolChildMap.Attributes["value"] = tagTagCommRsClientCertCACommHttpsCommPol.Value.ValueString() - } - CommRsClientCertCACommHttpsCommPolChildren = append(CommRsClientCertCACommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommRsClientCertCACommHttpsCommPolChildMap}) - } - } CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCACommHttpsCommPolChildMap}) } + for _, commHttpscommRsClientCertCAState := range commHttpsCommPolState { + commHttpscommRsClientCertCAState.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCACommHttpsCommPolState, false) + if len(commRsClientCertCACommHttpsCommPolPlan) == 0 && len(commRsClientCertCACommHttpsCommPolState) == 1 { + commRsClientCertCACommHttpsCommPolChildMap := NewAciObject() + commRsClientCertCACommHttpsCommPolChildMap.Attributes["status"] = "deleted" + CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCACommHttpsCommPolChildMap}) + } + } } + var commRsKeyRingCommHttpsCommPolPlan, commRsKeyRingCommHttpsCommPolState []CommRsKeyRingCommHttpsCommPolResourceModel commHttpsCommPol.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingCommHttpsCommPolPlan, false) - for _, commHttpscommRsKeyRingState := range commHttpsCommPolState { - commHttpscommRsKeyRingState.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingCommHttpsCommPolState, false) - if len(commRsKeyRingCommHttpsCommPolPlan) == 0 && len(commRsKeyRingCommHttpsCommPolState) == 1 { - diags.AddError( - "CommRsKeyRing object cannot be deleted", - "deletion of child is only possible upon deletion of the parent", - ) - return nil - } - } if !commHttpsCommPol.CommRsKeyRing.IsNull() && !commHttpsCommPol.CommRsKeyRing.IsUnknown() { for _, commRsKeyRingCommHttpsCommPol := range commRsKeyRingCommHttpsCommPolPlan { + commRsKeyRingCommHttpsCommPolChildMap := NewAciObject() if !commRsKeyRingCommHttpsCommPol.Annotation.IsNull() && !commRsKeyRingCommHttpsCommPol.Annotation.IsUnknown() { commRsKeyRingCommHttpsCommPolChildMap.Attributes["annotation"] = commRsKeyRingCommHttpsCommPol.Annotation.ValueString() } else { @@ -1636,63 +1249,26 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti if !commRsKeyRingCommHttpsCommPol.TnPkiKeyRingName.IsNull() && !commRsKeyRingCommHttpsCommPol.TnPkiKeyRingName.IsUnknown() { commRsKeyRingCommHttpsCommPolChildMap.Attributes["tnPkiKeyRingName"] = commRsKeyRingCommHttpsCommPol.TnPkiKeyRingName.ValueString() } - var tagAnnotationCommRsKeyRingCommHttpsCommPolPlan, tagAnnotationCommRsKeyRingCommHttpsCommPolState []TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel - commRsKeyRingCommHttpsCommPol.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommRsKeyRingCommHttpsCommPolPlan, false) - for _, commRsKeyRingtagAnnotationState := range commRsKeyRingCommHttpsCommPolState { - commRsKeyRingtagAnnotationState.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommRsKeyRingCommHttpsCommPolState, false) - if len(tagAnnotationCommRsKeyRingCommHttpsCommPolPlan) == 0 && len(tagAnnotationCommRsKeyRingCommHttpsCommPolState) == 1 { - tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap := NewAciObject() - tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap.Attributes["status"] = "deleted" - CommRsKeyRingCommHttpsCommPolChildren = append(CommRsKeyRingCommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap}) - } - } - if !commRsKeyRingCommHttpsCommPol.TagAnnotation.IsNull() && !commRsKeyRingCommHttpsCommPol.TagAnnotation.IsUnknown() { - for _, tagAnnotationCommRsKeyRingCommHttpsCommPol := range tagAnnotationCommRsKeyRingCommHttpsCommPolPlan { - if !tagAnnotationCommRsKeyRingCommHttpsCommPol.Key.IsNull() && !tagAnnotationCommRsKeyRingCommHttpsCommPol.Key.IsUnknown() { - tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap.Attributes["key"] = tagAnnotationCommRsKeyRingCommHttpsCommPol.Key.ValueString() - } - if !tagAnnotationCommRsKeyRingCommHttpsCommPol.Value.IsNull() && !tagAnnotationCommRsKeyRingCommHttpsCommPol.Value.IsUnknown() { - tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap.Attributes["value"] = tagAnnotationCommRsKeyRingCommHttpsCommPol.Value.ValueString() - } - CommRsKeyRingCommHttpsCommPolChildren = append(CommRsKeyRingCommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap}) - } - } - var tagTagCommRsKeyRingCommHttpsCommPolPlan, tagTagCommRsKeyRingCommHttpsCommPolState []TagTagCommRsKeyRingCommHttpsCommPolResourceModel - commRsKeyRingCommHttpsCommPol.TagTag.ElementsAs(ctx, &tagTagCommRsKeyRingCommHttpsCommPolPlan, false) - for _, commRsKeyRingtagTagState := range commRsKeyRingCommHttpsCommPolState { - commRsKeyRingtagTagState.TagTag.ElementsAs(ctx, &tagTagCommRsKeyRingCommHttpsCommPolState, false) - if len(tagTagCommRsKeyRingCommHttpsCommPolPlan) == 0 && len(tagTagCommRsKeyRingCommHttpsCommPolState) == 1 { - tagTagCommRsKeyRingCommHttpsCommPolChildMap := NewAciObject() - tagTagCommRsKeyRingCommHttpsCommPolChildMap.Attributes["status"] = "deleted" - CommRsKeyRingCommHttpsCommPolChildren = append(CommRsKeyRingCommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommRsKeyRingCommHttpsCommPolChildMap}) - } - } - if !commRsKeyRingCommHttpsCommPol.TagTag.IsNull() && !commRsKeyRingCommHttpsCommPol.TagTag.IsUnknown() { - for _, tagTagCommRsKeyRingCommHttpsCommPol := range tagTagCommRsKeyRingCommHttpsCommPolPlan { - if !tagTagCommRsKeyRingCommHttpsCommPol.Key.IsNull() && !tagTagCommRsKeyRingCommHttpsCommPol.Key.IsUnknown() { - tagTagCommRsKeyRingCommHttpsCommPolChildMap.Attributes["key"] = tagTagCommRsKeyRingCommHttpsCommPol.Key.ValueString() - } - if !tagTagCommRsKeyRingCommHttpsCommPol.Value.IsNull() && !tagTagCommRsKeyRingCommHttpsCommPol.Value.IsUnknown() { - tagTagCommRsKeyRingCommHttpsCommPolChildMap.Attributes["value"] = tagTagCommRsKeyRingCommHttpsCommPol.Value.ValueString() - } - CommRsKeyRingCommHttpsCommPolChildren = append(CommRsKeyRingCommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommRsKeyRingCommHttpsCommPolChildMap}) - } - } CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"commRsKeyRing": commRsKeyRingCommHttpsCommPolChildMap}) } + for _, commHttpscommRsKeyRingState := range commHttpsCommPolState { + commHttpscommRsKeyRingState.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingCommHttpsCommPolState, false) + if len(commRsKeyRingCommHttpsCommPolPlan) == 0 && len(commRsKeyRingCommHttpsCommPolState) == 1 { + diags.AddError( + "CommRsKeyRing object cannot be deleted", + "deletion of child is only possible upon deletion of the parent", + ) + return nil + } + } } + var tagAnnotationCommHttpsCommPolPlan, tagAnnotationCommHttpsCommPolState []TagAnnotationCommHttpsCommPolResourceModel commHttpsCommPol.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommHttpsCommPolPlan, false) - for _, commHttpstagAnnotationState := range commHttpsCommPolState { - commHttpstagAnnotationState.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommHttpsCommPolState, false) - if len(tagAnnotationCommHttpsCommPolPlan) == 0 && len(tagAnnotationCommHttpsCommPolState) == 1 { - tagAnnotationCommHttpsCommPolChildMap := NewAciObject() - tagAnnotationCommHttpsCommPolChildMap.Attributes["status"] = "deleted" - CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommHttpsCommPolChildMap}) - } - } if !commHttpsCommPol.TagAnnotation.IsNull() && !commHttpsCommPol.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotationCommHttpsCommPol := range tagAnnotationCommHttpsCommPolPlan { + tagAnnotationCommHttpsCommPolChildMap := NewAciObject() if !tagAnnotationCommHttpsCommPol.Key.IsNull() && !tagAnnotationCommHttpsCommPol.Key.IsUnknown() { tagAnnotationCommHttpsCommPolChildMap.Attributes["key"] = tagAnnotationCommHttpsCommPol.Key.ValueString() } @@ -1700,27 +1276,27 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti tagAnnotationCommHttpsCommPolChildMap.Attributes["value"] = tagAnnotationCommHttpsCommPol.Value.ValueString() } CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommHttpsCommPolChildMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationCommHttpsCommPol.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - } - var tagTagCommHttpsCommPolPlan, tagTagCommHttpsCommPolState []TagTagCommHttpsCommPolResourceModel - commHttpsCommPol.TagTag.ElementsAs(ctx, &tagTagCommHttpsCommPolPlan, false) - for _, commHttpstagTagState := range commHttpsCommPolState { - commHttpstagTagState.TagTag.ElementsAs(ctx, &tagTagCommHttpsCommPolState, false) - if len(tagTagCommHttpsCommPolPlan) == 0 && len(tagTagCommHttpsCommPolState) == 1 { - tagTagCommHttpsCommPolChildMap := NewAciObject() - tagTagCommHttpsCommPolChildMap.Attributes["status"] = "deleted" - CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommHttpsCommPolChildMap}) - } - } - if !commHttpsCommPol.TagTag.IsNull() && !commHttpsCommPol.TagTag.IsUnknown() { - for _, tagTagCommHttpsCommPol := range tagTagCommHttpsCommPolPlan { - if !tagTagCommHttpsCommPol.Key.IsNull() && !tagTagCommHttpsCommPol.Key.IsUnknown() { - tagTagCommHttpsCommPolChildMap.Attributes["key"] = tagTagCommHttpsCommPol.Key.ValueString() - } - if !tagTagCommHttpsCommPol.Value.IsNull() && !tagTagCommHttpsCommPol.Value.IsUnknown() { - tagTagCommHttpsCommPolChildMap.Attributes["value"] = tagTagCommHttpsCommPol.Value.ValueString() + for _, tagAnnotationCommHttpsCommPolstate := range commHttpsCommPolState { + tagAnnotationCommHttpsCommPolstate.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommHttpsCommPolState, false) + for _, tagAnnotationCommHttpsCommPol := range tagAnnotationCommHttpsCommPolState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotationCommHttpsCommPol.Key { + delete = false + break + } + } + if delete { + tagAnnotationCommHttpsCommPolChildMapForDelete := NewAciObject() + tagAnnotationCommHttpsCommPolChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationCommHttpsCommPolChildMapForDelete.Attributes["key"] = tagAnnotationCommHttpsCommPol.Key.ValueString() + CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommHttpsCommPolChildMapForDelete}) + } } - CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommHttpsCommPolChildMap}) } } childMap.Children = CommHttpsCommPolChildren @@ -1741,11 +1317,11 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti } func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, tagAnnotationCommPolPlan, tagAnnotationCommPolState []TagAnnotationCommPolResourceModel) []map[string]interface{} { - childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotationCommPol := range tagAnnotationCommPolPlan { + childMap := NewAciObject() if !tagAnnotationCommPol.Key.IsNull() && !tagAnnotationCommPol.Key.IsUnknown() { childMap.Attributes["key"] = tagAnnotationCommPol.Key.ValueString() } @@ -1780,11 +1356,11 @@ func getCommPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagn } func getCommPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, tagTagCommPolPlan, tagTagCommPolState []TagTagCommPolResourceModel) []map[string]interface{} { - childMap := NewAciObject() childPayloads := []map[string]interface{}{} if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} for _, tagTagCommPol := range tagTagCommPolPlan { + childMap := NewAciObject() if !tagTagCommPol.Key.IsNull() && !tagTagCommPol.Key.IsUnknown() { childMap.Attributes["key"] = tagTagCommPol.Key.ValueString() } diff --git a/internal/provider/resource_aci_endpoint_tag_ip.go b/internal/provider/resource_aci_endpoint_tag_ip.go index d760f7610..d2ecf878e 100644 --- a/internal/provider/resource_aci_endpoint_tag_ip.go +++ b/internal/provider/resource_aci_endpoint_tag_ip.go @@ -13,13 +13,11 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" @@ -42,50 +40,14 @@ type FvEpIpTagResource struct { // FvEpIpTagResourceModel describes the resource data model. type FvEpIpTagResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - CtxName types.String `tfsdk:"vrf_name"` - FvEpIpTagId types.String `tfsdk:"id_attribute"` - Ip types.String `tfsdk:"ip"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` -} - -// TagAnnotationFvEpIpTagResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationFvEpIpTagResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationFvEpIpTagResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationFvEpIpTagResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvEpIpTagResourceModelAttributeTypes()) -} - -// TagTagFvEpIpTagResourceModel describes the resource data model for the children without relation ships. -type TagTagFvEpIpTagResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagFvEpIpTagResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagFvEpIpTagResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvEpIpTagResourceModelAttributeTypes()) + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + CtxName types.String `tfsdk:"vrf_name"` + FvEpIpTagId types.String `tfsdk:"id_attribute"` + Ip types.String `tfsdk:"ip"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` } type FvEpIpTagIdentifier struct { @@ -176,62 +138,6 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque }, MarkdownDescription: `The name alias of the Endpoint Tag Ip object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of resource: aci_endpoint_tag_ip") @@ -261,11 +167,6 @@ func (r *FvEpIpTagResource) Configure(ctx context.Context, req resource.Configur func (r *FvEpIpTagResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_endpoint_tag_ip") - // On create retrieve information on current state prior to making any changes in order to determine child delete operations - var stateData *FvEpIpTagResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) - setFvEpIpTagId(ctx, stateData) - getAndSetFvEpIpTagAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *FvEpIpTagResourceModel @@ -280,13 +181,7 @@ func (r *FvEpIpTagResource) Create(ctx context.Context, req resource.CreateReque tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_endpoint_tag_ip with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpIpTagResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagFvEpIpTagResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getFvEpIpTagCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getFvEpIpTagCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -333,11 +228,9 @@ func (r *FvEpIpTagResource) Read(ctx context.Context, req resource.ReadRequest, func (r *FvEpIpTagResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_endpoint_tag_ip") var data *FvEpIpTagResourceModel - var stateData *FvEpIpTagResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -345,13 +238,7 @@ func (r *FvEpIpTagResource) Update(ctx context.Context, req resource.UpdateReque tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_endpoint_tag_ip with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpIpTagResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagFvEpIpTagResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getFvEpIpTagCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getFvEpIpTagCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -405,7 +292,7 @@ func (r *FvEpIpTagResource) ImportState(ctx context.Context, req resource.Import } func getAndSetFvEpIpTagAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *FvEpIpTagResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "fvEpIpTag,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -456,47 +343,6 @@ func getAndSetFvEpIpTagAttributes(ctx context.Context, diags *diag.Diagnostics, if data.NameAlias.IsUnknown() { data.NameAlias = types.StringNull() } - TagAnnotationFvEpIpTag := TagAnnotationFvEpIpTagResourceModel{} - TagAnnotationFvEpIpTagList := make([]TagAnnotationFvEpIpTagResourceModel, 0) - TagTagFvEpIpTag := TagTagFvEpIpTagResourceModel{} - TagTagFvEpIpTagList := make([]TagTagFvEpIpTagResourceModel, 0) - _, ok := classReadInfo[0].(map[string]interface{})["children"] - if ok { - children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) - for _, child := range children { - for childClassName, childClassDetails := range child.(map[string]interface{}) { - childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) - if childClassName == "tagAnnotation" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagAnnotationFvEpIpTag.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationFvEpIpTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagAnnotationFvEpIpTagList = append(TagAnnotationFvEpIpTagList, TagAnnotationFvEpIpTag) - } - if childClassName == "tagTag" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagTagFvEpIpTag.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagFvEpIpTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagTagFvEpIpTagList = append(TagTagFvEpIpTagList, TagTagFvEpIpTag) - } - } - } - } - tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationFvEpIpTagList) - data.TagAnnotation = tagAnnotationSet - tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagFvEpIpTagList) - data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -541,102 +387,9 @@ func setFvEpIpTagId(ctx context.Context, data *FvEpIpTagResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getFvEpIpTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagAnnotationFvEpIpTagPlan, tagAnnotationFvEpIpTagState []TagAnnotationFvEpIpTagResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { - tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotationFvEpIpTag := range tagAnnotationFvEpIpTagPlan { - if !tagAnnotationFvEpIpTag.Key.IsNull() && !tagAnnotationFvEpIpTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotationFvEpIpTag.Key.ValueString() - } - if !tagAnnotationFvEpIpTag.Value.IsNull() && !tagAnnotationFvEpIpTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotationFvEpIpTag.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) - tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotationFvEpIpTag.Key - tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) - } - for _, tagAnnotation := range tagAnnotationFvEpIpTagState { - delete := true - for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { - if tagAnnotationIdentifier.Key == tagAnnotation.Key { - delete = false - break - } - } - if delete { - tagAnnotationChildMapForDelete := NewAciObject() - tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" - tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) - } - } - } else { - data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) - } - - return childPayloads -} - -func getFvEpIpTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagTagFvEpIpTagPlan, tagTagFvEpIpTagState []TagTagFvEpIpTagResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { - tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTagFvEpIpTag := range tagTagFvEpIpTagPlan { - if !tagTagFvEpIpTag.Key.IsNull() && !tagTagFvEpIpTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagTagFvEpIpTag.Key.ValueString() - } - if !tagTagFvEpIpTag.Value.IsNull() && !tagTagFvEpIpTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagTagFvEpIpTag.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) - tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTagFvEpIpTag.Key - tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) - } - for _, tagTag := range tagTagFvEpIpTagState { - delete := true - for _, tagTagIdentifier := range tagTagIdentifiers { - if tagTagIdentifier.Key == tagTag.Key { - delete = false - break - } - } - if delete { - tagTagChildMapForDelete := NewAciObject() - tagTagChildMapForDelete.Attributes["status"] = "deleted" - tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) - } - } - } else { - data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) - } - - return childPayloads -} - -func getFvEpIpTagCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpIpTagResourceModel, tagTagPlan, tagTagState []TagTagFvEpIpTagResourceModel) *container.Container { +func getFvEpIpTagCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} - childPayloads := []map[string]interface{}{} - - TagAnnotationchildPayloads := getFvEpIpTagTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) - if TagAnnotationchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagAnnotationchildPayloads...) - - TagTagchildPayloads := getFvEpIpTagTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) - if TagTagchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagTagchildPayloads...) - - payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_endpoint_tag_ip_test.go b/internal/provider/resource_aci_endpoint_tag_ip_test.go index ca8f2a19f..3df9ba093 100644 --- a/internal/provider/resource_aci_endpoint_tag_ip_test.go +++ b/internal/provider/resource_aci_endpoint_tag_ip_test.go @@ -78,88 +78,6 @@ func TestAccResourceFvEpIpTagWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "name_alias", ""), ), }, - // Update with children - { - Config: testConfigFvEpIpTagChildrenDependencyWithFvTenant, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "ip", "10.0.0.2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "vrf_name", "test_ctx_name"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "id_attribute", "0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "name", ""), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.1.value", "value_2"), - ), - }, - // Import testing with children - { - ResourceName: "aci_endpoint_tag_ip.test", - ImportState: true, - ImportStateVerify: true, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "ip", "10.0.0.2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "vrf_name", "test_ctx_name"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "id_attribute", "0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "name", ""), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.1.value", "value_2"), - ), - }, - // Update with children removed from config - { - Config: testConfigFvEpIpTagChildrenRemoveFromConfigDependencyWithFvTenant, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.#", "2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.#", "2"), - ), - }, - // Update with children first child removed - { - Config: testConfigFvEpIpTagChildrenRemoveOneDependencyWithFvTenant, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.#", "1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.#", "1"), - ), - }, - // Update with all children removed - { - Config: testConfigFvEpIpTagChildrenRemoveAllDependencyWithFvTenant, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.#", "0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.#", "0"), - ), - }, }, }) } @@ -195,68 +113,3 @@ resource "aci_endpoint_tag_ip" "test" { name_alias = "" } ` -const testConfigFvEpIpTagChildrenDependencyWithFvTenant = testConfigFvTenantMin + ` -resource "aci_endpoint_tag_ip" "test" { - parent_dn = aci_tenant.test.id - ip = "10.0.0.2" - vrf_name = "test_ctx_name" - annotations = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigFvEpIpTagChildrenRemoveFromConfigDependencyWithFvTenant = testConfigFvTenantMin + ` -resource "aci_endpoint_tag_ip" "test" { - parent_dn = aci_tenant.test.id - ip = "10.0.0.2" - vrf_name = "test_ctx_name" -} -` - -const testConfigFvEpIpTagChildrenRemoveOneDependencyWithFvTenant = testConfigFvTenantMin + ` -resource "aci_endpoint_tag_ip" "test" { - parent_dn = aci_tenant.test.id - ip = "10.0.0.2" - vrf_name = "test_ctx_name" - annotations = [ - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigFvEpIpTagChildrenRemoveAllDependencyWithFvTenant = testConfigFvTenantMin + ` -resource "aci_endpoint_tag_ip" "test" { - parent_dn = aci_tenant.test.id - ip = "10.0.0.2" - vrf_name = "test_ctx_name" - annotations = [] - tags = [] -} -` diff --git a/internal/provider/resource_aci_endpoint_tag_mac.go b/internal/provider/resource_aci_endpoint_tag_mac.go index 6f119db10..3d9f7eb4c 100644 --- a/internal/provider/resource_aci_endpoint_tag_mac.go +++ b/internal/provider/resource_aci_endpoint_tag_mac.go @@ -13,13 +13,11 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" @@ -42,50 +40,14 @@ type FvEpMacTagResource struct { // FvEpMacTagResourceModel describes the resource data model. type FvEpMacTagResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - BdName types.String `tfsdk:"bd_name"` - FvEpMacTagId types.String `tfsdk:"id_attribute"` - Mac types.String `tfsdk:"mac"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` -} - -// TagAnnotationFvEpMacTagResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationFvEpMacTagResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationFvEpMacTagResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationFvEpMacTagResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvEpMacTagResourceModelAttributeTypes()) -} - -// TagTagFvEpMacTagResourceModel describes the resource data model for the children without relation ships. -type TagTagFvEpMacTagResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagFvEpMacTagResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagFvEpMacTagResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvEpMacTagResourceModelAttributeTypes()) + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + BdName types.String `tfsdk:"bd_name"` + FvEpMacTagId types.String `tfsdk:"id_attribute"` + Mac types.String `tfsdk:"mac"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` } type FvEpMacTagIdentifier struct { @@ -176,62 +138,6 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ }, MarkdownDescription: `The name alias of the Endpoint Tag Mac object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of resource: aci_endpoint_tag_mac") @@ -261,11 +167,6 @@ func (r *FvEpMacTagResource) Configure(ctx context.Context, req resource.Configu func (r *FvEpMacTagResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_endpoint_tag_mac") - // On create retrieve information on current state prior to making any changes in order to determine child delete operations - var stateData *FvEpMacTagResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) - setFvEpMacTagId(ctx, stateData) - getAndSetFvEpMacTagAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *FvEpMacTagResourceModel @@ -280,13 +181,7 @@ func (r *FvEpMacTagResource) Create(ctx context.Context, req resource.CreateRequ tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_endpoint_tag_mac with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpMacTagResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagFvEpMacTagResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getFvEpMacTagCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getFvEpMacTagCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -333,11 +228,9 @@ func (r *FvEpMacTagResource) Read(ctx context.Context, req resource.ReadRequest, func (r *FvEpMacTagResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_endpoint_tag_mac") var data *FvEpMacTagResourceModel - var stateData *FvEpMacTagResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -345,13 +238,7 @@ func (r *FvEpMacTagResource) Update(ctx context.Context, req resource.UpdateRequ tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_endpoint_tag_mac with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpMacTagResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagFvEpMacTagResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getFvEpMacTagCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getFvEpMacTagCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -405,7 +292,7 @@ func (r *FvEpMacTagResource) ImportState(ctx context.Context, req resource.Impor } func getAndSetFvEpMacTagAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *FvEpMacTagResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "fvEpMacTag,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -456,47 +343,6 @@ func getAndSetFvEpMacTagAttributes(ctx context.Context, diags *diag.Diagnostics, if data.NameAlias.IsUnknown() { data.NameAlias = types.StringNull() } - TagAnnotationFvEpMacTag := TagAnnotationFvEpMacTagResourceModel{} - TagAnnotationFvEpMacTagList := make([]TagAnnotationFvEpMacTagResourceModel, 0) - TagTagFvEpMacTag := TagTagFvEpMacTagResourceModel{} - TagTagFvEpMacTagList := make([]TagTagFvEpMacTagResourceModel, 0) - _, ok := classReadInfo[0].(map[string]interface{})["children"] - if ok { - children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) - for _, child := range children { - for childClassName, childClassDetails := range child.(map[string]interface{}) { - childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) - if childClassName == "tagAnnotation" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagAnnotationFvEpMacTag.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationFvEpMacTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagAnnotationFvEpMacTagList = append(TagAnnotationFvEpMacTagList, TagAnnotationFvEpMacTag) - } - if childClassName == "tagTag" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagTagFvEpMacTag.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagFvEpMacTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagTagFvEpMacTagList = append(TagTagFvEpMacTagList, TagTagFvEpMacTag) - } - } - } - } - tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationFvEpMacTagList) - data.TagAnnotation = tagAnnotationSet - tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagFvEpMacTagList) - data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -541,102 +387,9 @@ func setFvEpMacTagId(ctx context.Context, data *FvEpMacTagResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getFvEpMacTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagAnnotationFvEpMacTagPlan, tagAnnotationFvEpMacTagState []TagAnnotationFvEpMacTagResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { - tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotationFvEpMacTag := range tagAnnotationFvEpMacTagPlan { - if !tagAnnotationFvEpMacTag.Key.IsNull() && !tagAnnotationFvEpMacTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotationFvEpMacTag.Key.ValueString() - } - if !tagAnnotationFvEpMacTag.Value.IsNull() && !tagAnnotationFvEpMacTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotationFvEpMacTag.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) - tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotationFvEpMacTag.Key - tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) - } - for _, tagAnnotation := range tagAnnotationFvEpMacTagState { - delete := true - for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { - if tagAnnotationIdentifier.Key == tagAnnotation.Key { - delete = false - break - } - } - if delete { - tagAnnotationChildMapForDelete := NewAciObject() - tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" - tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) - } - } - } else { - data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) - } - - return childPayloads -} - -func getFvEpMacTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagTagFvEpMacTagPlan, tagTagFvEpMacTagState []TagTagFvEpMacTagResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { - tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTagFvEpMacTag := range tagTagFvEpMacTagPlan { - if !tagTagFvEpMacTag.Key.IsNull() && !tagTagFvEpMacTag.Key.IsUnknown() { - childMap.Attributes["key"] = tagTagFvEpMacTag.Key.ValueString() - } - if !tagTagFvEpMacTag.Value.IsNull() && !tagTagFvEpMacTag.Value.IsUnknown() { - childMap.Attributes["value"] = tagTagFvEpMacTag.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) - tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTagFvEpMacTag.Key - tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) - } - for _, tagTag := range tagTagFvEpMacTagState { - delete := true - for _, tagTagIdentifier := range tagTagIdentifiers { - if tagTagIdentifier.Key == tagTag.Key { - delete = false - break - } - } - if delete { - tagTagChildMapForDelete := NewAciObject() - tagTagChildMapForDelete.Attributes["status"] = "deleted" - tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) - } - } - } else { - data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) - } - - return childPayloads -} - -func getFvEpMacTagCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpMacTagResourceModel, tagTagPlan, tagTagState []TagTagFvEpMacTagResourceModel) *container.Container { +func getFvEpMacTagCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} - childPayloads := []map[string]interface{}{} - - TagAnnotationchildPayloads := getFvEpMacTagTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) - if TagAnnotationchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagAnnotationchildPayloads...) - - TagTagchildPayloads := getFvEpMacTagTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) - if TagTagchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagTagchildPayloads...) - - payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_endpoint_tag_mac_test.go b/internal/provider/resource_aci_endpoint_tag_mac_test.go index 5dd5781ef..71463e256 100644 --- a/internal/provider/resource_aci_endpoint_tag_mac_test.go +++ b/internal/provider/resource_aci_endpoint_tag_mac_test.go @@ -78,88 +78,6 @@ func TestAccResourceFvEpMacTagWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "name_alias", ""), ), }, - // Update with children - { - Config: testConfigFvEpMacTagChildrenDependencyWithFvTenant, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "bd_name", "test_bd_name"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "mac", "00:00:00:00:00:01"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "id_attribute", "0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "name", ""), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.1.value", "value_2"), - ), - }, - // Import testing with children - { - ResourceName: "aci_endpoint_tag_mac.test", - ImportState: true, - ImportStateVerify: true, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "bd_name", "test_bd_name"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "mac", "00:00:00:00:00:01"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "id_attribute", "0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "name", ""), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.1.value", "value_2"), - ), - }, - // Update with children removed from config - { - Config: testConfigFvEpMacTagChildrenRemoveFromConfigDependencyWithFvTenant, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.#", "2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.#", "2"), - ), - }, - // Update with children first child removed - { - Config: testConfigFvEpMacTagChildrenRemoveOneDependencyWithFvTenant, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.#", "1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.#", "1"), - ), - }, - // Update with all children removed - { - Config: testConfigFvEpMacTagChildrenRemoveAllDependencyWithFvTenant, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.#", "0"), - resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.#", "0"), - ), - }, }, }) } @@ -195,68 +113,3 @@ resource "aci_endpoint_tag_mac" "test" { name_alias = "" } ` -const testConfigFvEpMacTagChildrenDependencyWithFvTenant = testConfigFvTenantMin + ` -resource "aci_endpoint_tag_mac" "test" { - parent_dn = aci_tenant.test.id - bd_name = "test_bd_name" - mac = "00:00:00:00:00:01" - annotations = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigFvEpMacTagChildrenRemoveFromConfigDependencyWithFvTenant = testConfigFvTenantMin + ` -resource "aci_endpoint_tag_mac" "test" { - parent_dn = aci_tenant.test.id - bd_name = "test_bd_name" - mac = "00:00:00:00:00:01" -} -` - -const testConfigFvEpMacTagChildrenRemoveOneDependencyWithFvTenant = testConfigFvTenantMin + ` -resource "aci_endpoint_tag_mac" "test" { - parent_dn = aci_tenant.test.id - bd_name = "test_bd_name" - mac = "00:00:00:00:00:01" - annotations = [ - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigFvEpMacTagChildrenRemoveAllDependencyWithFvTenant = testConfigFvTenantMin + ` -resource "aci_endpoint_tag_mac" "test" { - parent_dn = aci_tenant.test.id - bd_name = "test_bd_name" - mac = "00:00:00:00:00:01" - annotations = [] - tags = [] -} -` 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 205f480be..ac3b57b21 100644 --- a/internal/provider/resource_aci_external_management_network_instance_profile.go +++ b/internal/provider/resource_aci_external_management_network_instance_profile.go @@ -51,8 +51,6 @@ type MgmtInstPResourceModel struct { NameAlias types.String `tfsdk:"name_alias"` Prio types.String `tfsdk:"priority"` MgmtRsOoBCons types.Set `tfsdk:"relation_to_consumed_out_of_band_contracts"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` } // MgmtRsOoBConsMgmtInstPResourceModel describes the resource data model for the children without relation ships. @@ -60,8 +58,6 @@ type MgmtRsOoBConsMgmtInstPResourceModel struct { Annotation types.String `tfsdk:"annotation"` Prio types.String `tfsdk:"priority"` TnVzOOBBrCPName types.String `tfsdk:"out_of_band_contract_name"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` } func MgmtRsOoBConsMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { @@ -69,8 +65,6 @@ func MgmtRsOoBConsMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { "annotation": types.StringType, "priority": types.StringType, "out_of_band_contract_name": types.StringType, - "annotations": types.SetType{ElemType: types.StringType}, - "tags": types.SetType{ElemType: types.StringType}, } } @@ -78,74 +72,6 @@ func MgmtRsOoBConsMgmtInstPResourceModelElementType() attr.TypeWithAttributeType return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, MgmtRsOoBConsMgmtInstPResourceModelAttributeTypes()) } -// TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationMgmtRsOoBConsMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationMgmtRsOoBConsMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtRsOoBConsMgmtInstPResourceModelAttributeTypes()) -} - -// TagTagMgmtRsOoBConsMgmtInstPResourceModel describes the resource data model for the children without relation ships. -type TagTagMgmtRsOoBConsMgmtInstPResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagMgmtRsOoBConsMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagMgmtRsOoBConsMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtRsOoBConsMgmtInstPResourceModelAttributeTypes()) -} - -// TagAnnotationMgmtInstPResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationMgmtInstPResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtInstPResourceModelAttributeTypes()) -} - -// TagTagMgmtInstPResourceModel describes the resource data model for the children without relation ships. -type TagTagMgmtInstPResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtInstPResourceModelAttributeTypes()) -} - type MgmtInstPIdentifier struct { Name types.String } @@ -257,118 +183,6 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque }, MarkdownDescription: `The name of the Out Of Band Contract object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - }, - }, - }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, }, }, }, @@ -423,13 +237,7 @@ func (r *MgmtInstPResource) Create(ctx context.Context, req resource.CreateReque var mgmtRsOoBConsPlan, mgmtRsOoBConsState []MgmtRsOoBConsMgmtInstPResourceModel data.MgmtRsOoBCons.ElementsAs(ctx, &mgmtRsOoBConsPlan, false) stateData.MgmtRsOoBCons.ElementsAs(ctx, &mgmtRsOoBConsState, false) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtInstPResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagMgmtInstPResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getMgmtInstPCreateJsonPayload(ctx, &resp.Diagnostics, data, mgmtRsOoBConsPlan, mgmtRsOoBConsState, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getMgmtInstPCreateJsonPayload(ctx, &resp.Diagnostics, data, mgmtRsOoBConsPlan, mgmtRsOoBConsState) if resp.Diagnostics.HasError() { return @@ -491,13 +299,7 @@ func (r *MgmtInstPResource) Update(ctx context.Context, req resource.UpdateReque var mgmtRsOoBConsPlan, mgmtRsOoBConsState []MgmtRsOoBConsMgmtInstPResourceModel data.MgmtRsOoBCons.ElementsAs(ctx, &mgmtRsOoBConsPlan, false) stateData.MgmtRsOoBCons.ElementsAs(ctx, &mgmtRsOoBConsState, false) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtInstPResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagMgmtInstPResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getMgmtInstPCreateJsonPayload(ctx, &resp.Diagnostics, data, mgmtRsOoBConsPlan, mgmtRsOoBConsState, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getMgmtInstPCreateJsonPayload(ctx, &resp.Diagnostics, data, mgmtRsOoBConsPlan, mgmtRsOoBConsState) if resp.Diagnostics.HasError() { return @@ -551,7 +353,7 @@ func (r *MgmtInstPResource) ImportState(ctx context.Context, req resource.Import } func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *MgmtInstPResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtInstP,mgmtRsOoBCons,tagAnnotation,tagTag,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtInstP,mgmtRsOoBCons"), "GET", nil) if diags.HasError() { return @@ -597,14 +399,6 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, } MgmtRsOoBConsMgmtInstP := MgmtRsOoBConsMgmtInstPResourceModel{} MgmtRsOoBConsMgmtInstPList := make([]MgmtRsOoBConsMgmtInstPResourceModel, 0) - TagAnnotationMgmtRsOoBConsMgmtInstP := TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel{} - TagAnnotationMgmtRsOoBConsMgmtInstPList := make([]TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel, 0) - TagTagMgmtRsOoBConsMgmtInstP := TagTagMgmtRsOoBConsMgmtInstPResourceModel{} - TagTagMgmtRsOoBConsMgmtInstPList := make([]TagTagMgmtRsOoBConsMgmtInstPResourceModel, 0) - TagAnnotationMgmtInstP := TagAnnotationMgmtInstPResourceModel{} - TagAnnotationMgmtInstPList := make([]TagAnnotationMgmtInstPResourceModel, 0) - TagTagMgmtInstP := TagTagMgmtInstPResourceModel{} - TagTagMgmtInstPList := make([]TagTagMgmtInstPResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) @@ -624,76 +418,13 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, } } - childrenOfMgmtRsOoBConsMgmtInstP, childrenOfMgmtRsOoBConsMgmtInstPExist := childClassDetails.(map[string]interface{})["children"] - if childrenOfMgmtRsOoBConsMgmtInstPExist { - for _, childMgmtRsOoBConsMgmtInstP := range childrenOfMgmtRsOoBConsMgmtInstP.([]interface{}) { - for childClassNameMgmtRsOoBConsMgmtInstP, childClassDetailsMgmtRsOoBConsMgmtInstP := range childMgmtRsOoBConsMgmtInstP.(map[string]interface{}) { - if childClassNameMgmtRsOoBConsMgmtInstP == "tagAnnotation" { - tagAnnotationchildAttributeValue := childClassDetailsMgmtRsOoBConsMgmtInstP.(map[string]interface{})["attributes"].(map[string]interface{}) - for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { - if childAttributeName == "key" { - TagAnnotationMgmtRsOoBConsMgmtInstP.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationMgmtRsOoBConsMgmtInstP.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - } - TagAnnotationMgmtRsOoBConsMgmtInstPList = append(TagAnnotationMgmtRsOoBConsMgmtInstPList, TagAnnotationMgmtRsOoBConsMgmtInstP) - } - if childClassNameMgmtRsOoBConsMgmtInstP == "tagTag" { - tagTagchildAttributeValue := childClassDetailsMgmtRsOoBConsMgmtInstP.(map[string]interface{})["attributes"].(map[string]interface{}) - for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { - if childAttributeName == "key" { - TagTagMgmtRsOoBConsMgmtInstP.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagMgmtRsOoBConsMgmtInstP.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - } - TagTagMgmtRsOoBConsMgmtInstPList = append(TagTagMgmtRsOoBConsMgmtInstPList, TagTagMgmtRsOoBConsMgmtInstP) - } - } - } - } - TagAnnotationSet, _ := types.SetValueFrom(ctx, TagAnnotationMgmtRsOoBConsMgmtInstPResourceModelElementType(), TagAnnotationMgmtRsOoBConsMgmtInstPList) - MgmtRsOoBConsMgmtInstP.TagAnnotation = TagAnnotationSet - TagTagSet, _ := types.SetValueFrom(ctx, TagTagMgmtRsOoBConsMgmtInstPResourceModelElementType(), TagTagMgmtRsOoBConsMgmtInstPList) - MgmtRsOoBConsMgmtInstP.TagTag = TagTagSet MgmtRsOoBConsMgmtInstPList = append(MgmtRsOoBConsMgmtInstPList, MgmtRsOoBConsMgmtInstP) } - if childClassName == "tagAnnotation" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagAnnotationMgmtInstP.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationMgmtInstP.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagAnnotationMgmtInstPList = append(TagAnnotationMgmtInstPList, TagAnnotationMgmtInstP) - } - if childClassName == "tagTag" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagTagMgmtInstP.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagMgmtInstP.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagTagMgmtInstPList = append(TagTagMgmtInstPList, TagTagMgmtInstP) - } } } } mgmtRsOoBConsSet, _ := types.SetValueFrom(ctx, data.MgmtRsOoBCons.ElementType(ctx), MgmtRsOoBConsMgmtInstPList) data.MgmtRsOoBCons = mgmtRsOoBConsSet - tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationMgmtInstPList) - data.TagAnnotation = tagAnnotationSet - tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagMgmtInstPList) - data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -721,14 +452,11 @@ func setMgmtInstPId(ctx context.Context, data *MgmtInstPResourceModel) { } func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, mgmtRsOoBConsMgmtInstPPlan, mgmtRsOoBConsMgmtInstPState []MgmtRsOoBConsMgmtInstPResourceModel) []map[string]interface{} { - childMap := NewAciObject() childPayloads := []map[string]interface{}{} - tagAnnotationMgmtRsOoBConsMgmtInstPChildMap := NewAciObject() - tagTagMgmtRsOoBConsMgmtInstPChildMap := NewAciObject() - MgmtRsOoBConsMgmtInstPChildren := make([]map[string]interface{}, 0) if !data.MgmtRsOoBCons.IsNull() && !data.MgmtRsOoBCons.IsUnknown() { mgmtRsOoBConsIdentifiers := []MgmtRsOoBConsIdentifier{} for _, mgmtRsOoBConsMgmtInstP := range mgmtRsOoBConsMgmtInstPPlan { + childMap := NewAciObject() if !mgmtRsOoBConsMgmtInstP.Annotation.IsNull() && !mgmtRsOoBConsMgmtInstP.Annotation.IsUnknown() { childMap.Attributes["annotation"] = mgmtRsOoBConsMgmtInstP.Annotation.ValueString() } else { @@ -740,49 +468,6 @@ func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Dia if !mgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName.IsNull() && !mgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName.IsUnknown() { childMap.Attributes["tnVzOOBBrCPName"] = mgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName.ValueString() } - var tagAnnotationMgmtRsOoBConsMgmtInstPPlan, tagAnnotationMgmtRsOoBConsMgmtInstPState []TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel - mgmtRsOoBConsMgmtInstP.TagAnnotation.ElementsAs(ctx, &tagAnnotationMgmtRsOoBConsMgmtInstPPlan, false) - for _, mgmtRsOoBConstagAnnotationState := range mgmtRsOoBConsMgmtInstPState { - mgmtRsOoBConstagAnnotationState.TagAnnotation.ElementsAs(ctx, &tagAnnotationMgmtRsOoBConsMgmtInstPState, false) - if len(tagAnnotationMgmtRsOoBConsMgmtInstPPlan) == 0 && len(tagAnnotationMgmtRsOoBConsMgmtInstPState) == 1 { - tagAnnotationMgmtRsOoBConsMgmtInstPChildMap := NewAciObject() - tagAnnotationMgmtRsOoBConsMgmtInstPChildMap.Attributes["status"] = "deleted" - MgmtRsOoBConsMgmtInstPChildren = append(MgmtRsOoBConsMgmtInstPChildren, map[string]interface{}{"tagAnnotation": tagAnnotationMgmtRsOoBConsMgmtInstPChildMap}) - } - } - if !mgmtRsOoBConsMgmtInstP.TagAnnotation.IsNull() && !mgmtRsOoBConsMgmtInstP.TagAnnotation.IsUnknown() { - for _, tagAnnotationMgmtRsOoBConsMgmtInstP := range tagAnnotationMgmtRsOoBConsMgmtInstPPlan { - if !tagAnnotationMgmtRsOoBConsMgmtInstP.Key.IsNull() && !tagAnnotationMgmtRsOoBConsMgmtInstP.Key.IsUnknown() { - tagAnnotationMgmtRsOoBConsMgmtInstPChildMap.Attributes["key"] = tagAnnotationMgmtRsOoBConsMgmtInstP.Key.ValueString() - } - if !tagAnnotationMgmtRsOoBConsMgmtInstP.Value.IsNull() && !tagAnnotationMgmtRsOoBConsMgmtInstP.Value.IsUnknown() { - tagAnnotationMgmtRsOoBConsMgmtInstPChildMap.Attributes["value"] = tagAnnotationMgmtRsOoBConsMgmtInstP.Value.ValueString() - } - MgmtRsOoBConsMgmtInstPChildren = append(MgmtRsOoBConsMgmtInstPChildren, map[string]interface{}{"tagAnnotation": tagAnnotationMgmtRsOoBConsMgmtInstPChildMap}) - } - } - var tagTagMgmtRsOoBConsMgmtInstPPlan, tagTagMgmtRsOoBConsMgmtInstPState []TagTagMgmtRsOoBConsMgmtInstPResourceModel - mgmtRsOoBConsMgmtInstP.TagTag.ElementsAs(ctx, &tagTagMgmtRsOoBConsMgmtInstPPlan, false) - for _, mgmtRsOoBConstagTagState := range mgmtRsOoBConsMgmtInstPState { - mgmtRsOoBConstagTagState.TagTag.ElementsAs(ctx, &tagTagMgmtRsOoBConsMgmtInstPState, false) - if len(tagTagMgmtRsOoBConsMgmtInstPPlan) == 0 && len(tagTagMgmtRsOoBConsMgmtInstPState) == 1 { - tagTagMgmtRsOoBConsMgmtInstPChildMap := NewAciObject() - tagTagMgmtRsOoBConsMgmtInstPChildMap.Attributes["status"] = "deleted" - MgmtRsOoBConsMgmtInstPChildren = append(MgmtRsOoBConsMgmtInstPChildren, map[string]interface{}{"tagTag": tagTagMgmtRsOoBConsMgmtInstPChildMap}) - } - } - if !mgmtRsOoBConsMgmtInstP.TagTag.IsNull() && !mgmtRsOoBConsMgmtInstP.TagTag.IsUnknown() { - for _, tagTagMgmtRsOoBConsMgmtInstP := range tagTagMgmtRsOoBConsMgmtInstPPlan { - if !tagTagMgmtRsOoBConsMgmtInstP.Key.IsNull() && !tagTagMgmtRsOoBConsMgmtInstP.Key.IsUnknown() { - tagTagMgmtRsOoBConsMgmtInstPChildMap.Attributes["key"] = tagTagMgmtRsOoBConsMgmtInstP.Key.ValueString() - } - if !tagTagMgmtRsOoBConsMgmtInstP.Value.IsNull() && !tagTagMgmtRsOoBConsMgmtInstP.Value.IsUnknown() { - tagTagMgmtRsOoBConsMgmtInstPChildMap.Attributes["value"] = tagTagMgmtRsOoBConsMgmtInstP.Value.ValueString() - } - MgmtRsOoBConsMgmtInstPChildren = append(MgmtRsOoBConsMgmtInstPChildren, map[string]interface{}{"tagTag": tagTagMgmtRsOoBConsMgmtInstPChildMap}) - } - } - childMap.Children = MgmtRsOoBConsMgmtInstPChildren childPayloads = append(childPayloads, map[string]interface{}{"mgmtRsOoBCons": childMap}) mgmtRsOoBConsIdentifier := MgmtRsOoBConsIdentifier{} mgmtRsOoBConsIdentifier.TnVzOOBBrCPName = mgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName @@ -810,85 +495,7 @@ func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Dia return childPayloads } -func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagAnnotationMgmtInstPPlan, tagAnnotationMgmtInstPState []TagAnnotationMgmtInstPResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { - tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotationMgmtInstP := range tagAnnotationMgmtInstPPlan { - if !tagAnnotationMgmtInstP.Key.IsNull() && !tagAnnotationMgmtInstP.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotationMgmtInstP.Key.ValueString() - } - if !tagAnnotationMgmtInstP.Value.IsNull() && !tagAnnotationMgmtInstP.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotationMgmtInstP.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) - tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotationMgmtInstP.Key - tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) - } - for _, tagAnnotation := range tagAnnotationMgmtInstPState { - delete := true - for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { - if tagAnnotationIdentifier.Key == tagAnnotation.Key { - delete = false - break - } - } - if delete { - tagAnnotationChildMapForDelete := NewAciObject() - tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" - tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) - } - } - } else { - data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) - } - - return childPayloads -} - -func getMgmtInstPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagTagMgmtInstPPlan, tagTagMgmtInstPState []TagTagMgmtInstPResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { - tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTagMgmtInstP := range tagTagMgmtInstPPlan { - if !tagTagMgmtInstP.Key.IsNull() && !tagTagMgmtInstP.Key.IsUnknown() { - childMap.Attributes["key"] = tagTagMgmtInstP.Key.ValueString() - } - if !tagTagMgmtInstP.Value.IsNull() && !tagTagMgmtInstP.Value.IsUnknown() { - childMap.Attributes["value"] = tagTagMgmtInstP.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) - tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTagMgmtInstP.Key - tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) - } - for _, tagTag := range tagTagMgmtInstPState { - delete := true - for _, tagTagIdentifier := range tagTagIdentifiers { - if tagTagIdentifier.Key == tagTag.Key { - delete = false - break - } - } - if delete { - tagTagChildMapForDelete := NewAciObject() - tagTagChildMapForDelete.Attributes["status"] = "deleted" - tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) - } - } - } else { - data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) - } - - return childPayloads -} - -func getMgmtInstPCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, mgmtRsOoBConsPlan, mgmtRsOoBConsState []MgmtRsOoBConsMgmtInstPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtInstPResourceModel, tagTagPlan, tagTagState []TagTagMgmtInstPResourceModel) *container.Container { +func getMgmtInstPCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, mgmtRsOoBConsPlan, mgmtRsOoBConsState []MgmtRsOoBConsMgmtInstPResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} childPayloads := []map[string]interface{}{} @@ -899,18 +506,6 @@ func getMgmtInstPCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, } childPayloads = append(childPayloads, MgmtRsOoBConschildPayloads...) - TagAnnotationchildPayloads := getMgmtInstPTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) - if TagAnnotationchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagAnnotationchildPayloads...) - - TagTagchildPayloads := getMgmtInstPTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) - if TagTagchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagTagchildPayloads...) - payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() diff --git a/internal/provider/resource_aci_external_management_network_instance_profile_test.go b/internal/provider/resource_aci_external_management_network_instance_profile_test.go index 32808d79d..d69a86416 100644 --- a/internal/provider/resource_aci_external_management_network_instance_profile_test.go +++ b/internal/provider/resource_aci_external_management_network_instance_profile_test.go @@ -81,11 +81,6 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "description", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "name_alias", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "priority", "unspecified"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.#", "2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level1"), @@ -93,11 +88,6 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.priority", "level2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.#", "2"), ), }, // Update with children removed from config @@ -108,11 +98,6 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "description", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "name_alias", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "priority", "unspecified"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.#", "2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level1"), @@ -120,11 +105,6 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.priority", "level2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.#", "2"), ), }, // Update with children first child removed @@ -135,16 +115,10 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "description", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "name_alias", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "priority", "unspecified"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.#", "1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.annotation", "annotation_2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "1"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.#", "1"), ), }, // Update with all children removed @@ -155,9 +129,7 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "description", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "name_alias", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "priority", "unspecified"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.#", "0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "0"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.#", "0"), ), }, }, @@ -192,16 +164,6 @@ resource "aci_external_management_network_instance_profile" "test" { const testConfigMgmtInstPChildren = ` resource "aci_external_management_network_instance_profile" "test" { name = "test_name" - annotations = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] relation_to_consumed_out_of_band_contracts = [ { annotation = "annotation_1" @@ -214,16 +176,6 @@ resource "aci_external_management_network_instance_profile" "test" { priority = "level2" }, ] - tags = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] } ` @@ -236,12 +188,6 @@ resource "aci_external_management_network_instance_profile" "test" { const testConfigMgmtInstPChildrenRemoveOne = ` resource "aci_external_management_network_instance_profile" "test" { name = "test_name" - annotations = [ - { - key = "key_1" - value = "value_2" - }, - ] relation_to_consumed_out_of_band_contracts = [ { annotation = "annotation_2" @@ -249,20 +195,12 @@ resource "aci_external_management_network_instance_profile" "test" { priority = "level2" }, ] - tags = [ - { - key = "key_1" - value = "value_2" - }, - ] } ` const testConfigMgmtInstPChildrenRemoveAll = ` resource "aci_external_management_network_instance_profile" "test" { name = "test_name" - annotations = [] relation_to_consumed_out_of_band_contracts = [] - tags = [] } ` diff --git a/internal/provider/resource_aci_external_management_network_subnet.go b/internal/provider/resource_aci_external_management_network_subnet.go index c09a9aaae..2b5d1e6b3 100644 --- a/internal/provider/resource_aci_external_management_network_subnet.go +++ b/internal/provider/resource_aci_external_management_network_subnet.go @@ -13,13 +13,11 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" @@ -42,49 +40,13 @@ type MgmtSubnetResource struct { // MgmtSubnetResourceModel describes the resource data model. type MgmtSubnetResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Ip types.String `tfsdk:"ip"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` -} - -// TagAnnotationMgmtSubnetResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationMgmtSubnetResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationMgmtSubnetResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationMgmtSubnetResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtSubnetResourceModelAttributeTypes()) -} - -// TagTagMgmtSubnetResourceModel describes the resource data model for the children without relation ships. -type TagTagMgmtSubnetResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagMgmtSubnetResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagMgmtSubnetResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtSubnetResourceModelAttributeTypes()) + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Ip types.String `tfsdk:"ip"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` } type MgmtSubnetIdentifier struct { @@ -165,62 +127,6 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ }, MarkdownDescription: `The name alias of the External Management Network Subnet object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of resource: aci_external_management_network_subnet") @@ -250,11 +156,6 @@ func (r *MgmtSubnetResource) Configure(ctx context.Context, req resource.Configu func (r *MgmtSubnetResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_external_management_network_subnet") - // On create retrieve information on current state prior to making any changes in order to determine child delete operations - var stateData *MgmtSubnetResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) - setMgmtSubnetId(ctx, stateData) - getAndSetMgmtSubnetAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *MgmtSubnetResourceModel @@ -269,13 +170,7 @@ func (r *MgmtSubnetResource) Create(ctx context.Context, req resource.CreateRequ tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_external_management_network_subnet with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtSubnetResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagMgmtSubnetResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getMgmtSubnetCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getMgmtSubnetCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -322,11 +217,9 @@ func (r *MgmtSubnetResource) Read(ctx context.Context, req resource.ReadRequest, func (r *MgmtSubnetResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_external_management_network_subnet") var data *MgmtSubnetResourceModel - var stateData *MgmtSubnetResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -334,13 +227,7 @@ func (r *MgmtSubnetResource) Update(ctx context.Context, req resource.UpdateRequ tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_external_management_network_subnet with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtSubnetResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagMgmtSubnetResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getMgmtSubnetCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getMgmtSubnetCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -394,7 +281,7 @@ func (r *MgmtSubnetResource) ImportState(ctx context.Context, req resource.Impor } func getAndSetMgmtSubnetAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *MgmtSubnetResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtSubnet,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -439,47 +326,6 @@ func getAndSetMgmtSubnetAttributes(ctx context.Context, diags *diag.Diagnostics, if data.NameAlias.IsUnknown() { data.NameAlias = types.StringNull() } - TagAnnotationMgmtSubnet := TagAnnotationMgmtSubnetResourceModel{} - TagAnnotationMgmtSubnetList := make([]TagAnnotationMgmtSubnetResourceModel, 0) - TagTagMgmtSubnet := TagTagMgmtSubnetResourceModel{} - TagTagMgmtSubnetList := make([]TagTagMgmtSubnetResourceModel, 0) - _, ok := classReadInfo[0].(map[string]interface{})["children"] - if ok { - children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) - for _, child := range children { - for childClassName, childClassDetails := range child.(map[string]interface{}) { - childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) - if childClassName == "tagAnnotation" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagAnnotationMgmtSubnet.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationMgmtSubnet.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagAnnotationMgmtSubnetList = append(TagAnnotationMgmtSubnetList, TagAnnotationMgmtSubnet) - } - if childClassName == "tagTag" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagTagMgmtSubnet.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagMgmtSubnet.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagTagMgmtSubnetList = append(TagTagMgmtSubnetList, TagTagMgmtSubnet) - } - } - } - } - tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationMgmtSubnetList) - data.TagAnnotation = tagAnnotationSet - tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagMgmtSubnetList) - data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -522,102 +368,9 @@ func setMgmtSubnetId(ctx context.Context, data *MgmtSubnetResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getMgmtSubnetTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagAnnotationMgmtSubnetPlan, tagAnnotationMgmtSubnetState []TagAnnotationMgmtSubnetResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { - tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotationMgmtSubnet := range tagAnnotationMgmtSubnetPlan { - if !tagAnnotationMgmtSubnet.Key.IsNull() && !tagAnnotationMgmtSubnet.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotationMgmtSubnet.Key.ValueString() - } - if !tagAnnotationMgmtSubnet.Value.IsNull() && !tagAnnotationMgmtSubnet.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotationMgmtSubnet.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) - tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotationMgmtSubnet.Key - tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) - } - for _, tagAnnotation := range tagAnnotationMgmtSubnetState { - delete := true - for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { - if tagAnnotationIdentifier.Key == tagAnnotation.Key { - delete = false - break - } - } - if delete { - tagAnnotationChildMapForDelete := NewAciObject() - tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" - tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) - } - } - } else { - data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) - } - - return childPayloads -} - -func getMgmtSubnetTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagTagMgmtSubnetPlan, tagTagMgmtSubnetState []TagTagMgmtSubnetResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { - tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTagMgmtSubnet := range tagTagMgmtSubnetPlan { - if !tagTagMgmtSubnet.Key.IsNull() && !tagTagMgmtSubnet.Key.IsUnknown() { - childMap.Attributes["key"] = tagTagMgmtSubnet.Key.ValueString() - } - if !tagTagMgmtSubnet.Value.IsNull() && !tagTagMgmtSubnet.Value.IsUnknown() { - childMap.Attributes["value"] = tagTagMgmtSubnet.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) - tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTagMgmtSubnet.Key - tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) - } - for _, tagTag := range tagTagMgmtSubnetState { - delete := true - for _, tagTagIdentifier := range tagTagIdentifiers { - if tagTagIdentifier.Key == tagTag.Key { - delete = false - break - } - } - if delete { - tagTagChildMapForDelete := NewAciObject() - tagTagChildMapForDelete.Attributes["status"] = "deleted" - tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) - } - } - } else { - data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) - } - - return childPayloads -} - -func getMgmtSubnetCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtSubnetResourceModel, tagTagPlan, tagTagState []TagTagMgmtSubnetResourceModel) *container.Container { +func getMgmtSubnetCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} - childPayloads := []map[string]interface{}{} - - TagAnnotationchildPayloads := getMgmtSubnetTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) - if TagAnnotationchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagAnnotationchildPayloads...) - - TagTagchildPayloads := getMgmtSubnetTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) - if TagTagchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagTagchildPayloads...) - - payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_external_management_network_subnet_test.go b/internal/provider/resource_aci_external_management_network_subnet_test.go index 6bdd85a8f..369d3007f 100644 --- a/internal/provider/resource_aci_external_management_network_subnet_test.go +++ b/internal/provider/resource_aci_external_management_network_subnet_test.go @@ -73,86 +73,6 @@ func TestAccResourceMgmtSubnetWithMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "name_alias", ""), ), }, - // Update with children - { - Config: testConfigMgmtSubnetChildrenDependencyWithMgmtInstP, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "ip", "1.1.1.0/24"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "description", ""), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "name", ""), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.1.value", "value_2"), - ), - }, - // Import testing with children - { - ResourceName: "aci_external_management_network_subnet.test", - ImportState: true, - ImportStateVerify: true, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "ip", "1.1.1.0/24"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "description", ""), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "name", ""), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.1.value", "value_2"), - ), - }, - // Update with children removed from config - { - Config: testConfigMgmtSubnetChildrenRemoveFromConfigDependencyWithMgmtInstP, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.#", "2"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.#", "2"), - ), - }, - // Update with children first child removed - { - Config: testConfigMgmtSubnetChildrenRemoveOneDependencyWithMgmtInstP, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.#", "1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.#", "1"), - ), - }, - // Update with all children removed - { - Config: testConfigMgmtSubnetChildrenRemoveAllDependencyWithMgmtInstP, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.#", "0"), - resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.#", "0"), - ), - }, }, }) } @@ -185,64 +105,3 @@ resource "aci_external_management_network_subnet" "test" { name_alias = "" } ` -const testConfigMgmtSubnetChildrenDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` -resource "aci_external_management_network_subnet" "test" { - parent_dn = aci_external_management_network_instance_profile.test.id - ip = "1.1.1.0/24" - annotations = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigMgmtSubnetChildrenRemoveFromConfigDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` -resource "aci_external_management_network_subnet" "test" { - parent_dn = aci_external_management_network_instance_profile.test.id - ip = "1.1.1.0/24" -} -` - -const testConfigMgmtSubnetChildrenRemoveOneDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` -resource "aci_external_management_network_subnet" "test" { - parent_dn = aci_external_management_network_instance_profile.test.id - ip = "1.1.1.0/24" - annotations = [ - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigMgmtSubnetChildrenRemoveAllDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` -resource "aci_external_management_network_subnet" "test" { - parent_dn = aci_external_management_network_instance_profile.test.id - ip = "1.1.1.0/24" - annotations = [] - tags = [] -} -` diff --git a/internal/provider/resource_aci_l3out_consumer_label.go b/internal/provider/resource_aci_l3out_consumer_label.go index 5ec47f1fa..9438dc3b5 100644 --- a/internal/provider/resource_aci_l3out_consumer_label.go +++ b/internal/provider/resource_aci_l3out_consumer_label.go @@ -14,13 +14,11 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -44,52 +42,16 @@ type L3extConsLblResource struct { // L3extConsLblResourceModel describes the resource data model. type L3extConsLblResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - Owner types.String `tfsdk:"owner"` - OwnerKey types.String `tfsdk:"owner_key"` - OwnerTag types.String `tfsdk:"owner_tag"` - Tag types.String `tfsdk:"tag"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` -} - -// TagAnnotationL3extConsLblResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationL3extConsLblResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationL3extConsLblResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationL3extConsLblResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationL3extConsLblResourceModelAttributeTypes()) -} - -// TagTagL3extConsLblResourceModel describes the resource data model for the children without relation ships. -type TagTagL3extConsLblResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagL3extConsLblResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagL3extConsLblResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagL3extConsLblResourceModelAttributeTypes()) + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + Owner types.String `tfsdk:"owner"` + OwnerKey types.String `tfsdk:"owner_key"` + OwnerTag types.String `tfsdk:"owner_tag"` + Tag types.String `tfsdk:"tag"` } type L3extConsLblIdentifier struct { @@ -203,62 +165,6 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe }, MarkdownDescription: `Specifies the color of a policy label.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of resource: aci_l3out_consumer_label") @@ -288,11 +194,6 @@ func (r *L3extConsLblResource) Configure(ctx context.Context, req resource.Confi func (r *L3extConsLblResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_l3out_consumer_label") - // On create retrieve information on current state prior to making any changes in order to determine child delete operations - var stateData *L3extConsLblResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) - setL3extConsLblId(ctx, stateData) - getAndSetL3extConsLblAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *L3extConsLblResourceModel @@ -307,13 +208,7 @@ func (r *L3extConsLblResource) Create(ctx context.Context, req resource.CreateRe tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_l3out_consumer_label with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extConsLblResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagL3extConsLblResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getL3extConsLblCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getL3extConsLblCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -360,11 +255,9 @@ func (r *L3extConsLblResource) Read(ctx context.Context, req resource.ReadReques func (r *L3extConsLblResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_l3out_consumer_label") var data *L3extConsLblResourceModel - var stateData *L3extConsLblResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -372,13 +265,7 @@ func (r *L3extConsLblResource) Update(ctx context.Context, req resource.UpdateRe tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_l3out_consumer_label with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extConsLblResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagL3extConsLblResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getL3extConsLblCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getL3extConsLblCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -432,7 +319,7 @@ func (r *L3extConsLblResource) ImportState(ctx context.Context, req resource.Imp } func getAndSetL3extConsLblAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *L3extConsLblResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "l3extConsLbl,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -495,47 +382,6 @@ func getAndSetL3extConsLblAttributes(ctx context.Context, diags *diag.Diagnostic if data.Tag.IsUnknown() { data.Tag = types.StringNull() } - TagAnnotationL3extConsLbl := TagAnnotationL3extConsLblResourceModel{} - TagAnnotationL3extConsLblList := make([]TagAnnotationL3extConsLblResourceModel, 0) - TagTagL3extConsLbl := TagTagL3extConsLblResourceModel{} - TagTagL3extConsLblList := make([]TagTagL3extConsLblResourceModel, 0) - _, ok := classReadInfo[0].(map[string]interface{})["children"] - if ok { - children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) - for _, child := range children { - for childClassName, childClassDetails := range child.(map[string]interface{}) { - childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) - if childClassName == "tagAnnotation" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagAnnotationL3extConsLbl.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationL3extConsLbl.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagAnnotationL3extConsLblList = append(TagAnnotationL3extConsLblList, TagAnnotationL3extConsLbl) - } - if childClassName == "tagTag" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagTagL3extConsLbl.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagL3extConsLbl.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagTagL3extConsLblList = append(TagTagL3extConsLblList, TagTagL3extConsLbl) - } - } - } - } - tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationL3extConsLblList) - data.TagAnnotation = tagAnnotationSet - tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagL3extConsLblList) - data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -578,102 +424,9 @@ func setL3extConsLblId(ctx context.Context, data *L3extConsLblResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getL3extConsLblTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagAnnotationL3extConsLblPlan, tagAnnotationL3extConsLblState []TagAnnotationL3extConsLblResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { - tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotationL3extConsLbl := range tagAnnotationL3extConsLblPlan { - if !tagAnnotationL3extConsLbl.Key.IsNull() && !tagAnnotationL3extConsLbl.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotationL3extConsLbl.Key.ValueString() - } - if !tagAnnotationL3extConsLbl.Value.IsNull() && !tagAnnotationL3extConsLbl.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotationL3extConsLbl.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) - tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotationL3extConsLbl.Key - tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) - } - for _, tagAnnotation := range tagAnnotationL3extConsLblState { - delete := true - for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { - if tagAnnotationIdentifier.Key == tagAnnotation.Key { - delete = false - break - } - } - if delete { - tagAnnotationChildMapForDelete := NewAciObject() - tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" - tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) - } - } - } else { - data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) - } - - return childPayloads -} - -func getL3extConsLblTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagTagL3extConsLblPlan, tagTagL3extConsLblState []TagTagL3extConsLblResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { - tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTagL3extConsLbl := range tagTagL3extConsLblPlan { - if !tagTagL3extConsLbl.Key.IsNull() && !tagTagL3extConsLbl.Key.IsUnknown() { - childMap.Attributes["key"] = tagTagL3extConsLbl.Key.ValueString() - } - if !tagTagL3extConsLbl.Value.IsNull() && !tagTagL3extConsLbl.Value.IsUnknown() { - childMap.Attributes["value"] = tagTagL3extConsLbl.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) - tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTagL3extConsLbl.Key - tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) - } - for _, tagTag := range tagTagL3extConsLblState { - delete := true - for _, tagTagIdentifier := range tagTagIdentifiers { - if tagTagIdentifier.Key == tagTag.Key { - delete = false - break - } - } - if delete { - tagTagChildMapForDelete := NewAciObject() - tagTagChildMapForDelete.Attributes["status"] = "deleted" - tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) - } - } - } else { - data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) - } - - return childPayloads -} - -func getL3extConsLblCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extConsLblResourceModel, tagTagPlan, tagTagState []TagTagL3extConsLblResourceModel) *container.Container { +func getL3extConsLblCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} - childPayloads := []map[string]interface{}{} - - TagAnnotationchildPayloads := getL3extConsLblTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) - if TagAnnotationchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagAnnotationchildPayloads...) - - TagTagchildPayloads := getL3extConsLblTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) - if TagTagchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagTagchildPayloads...) - - payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_l3out_consumer_label_test.go b/internal/provider/resource_aci_l3out_consumer_label_test.go index 01a8459da..f6c3bed49 100644 --- a/internal/provider/resource_aci_l3out_consumer_label_test.go +++ b/internal/provider/resource_aci_l3out_consumer_label_test.go @@ -85,92 +85,6 @@ func TestAccResourceL3extConsLblWithL3extOut(t *testing.T) { resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tag", "yellow-green"), ), }, - // Update with children - { - Config: testConfigL3extConsLblChildrenDependencyWithL3extOut, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "name", "test_name"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "description", ""), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "owner", "infra"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "owner_key", ""), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "owner_tag", ""), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tag", "yellow-green"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.1.value", "value_2"), - ), - }, - // Import testing with children - { - ResourceName: "aci_l3out_consumer_label.test", - ImportState: true, - ImportStateVerify: true, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "name", "test_name"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "description", ""), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "owner", "infra"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "owner_key", ""), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "owner_tag", ""), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tag", "yellow-green"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.1.value", "value_2"), - ), - }, - // Update with children removed from config - { - Config: testConfigL3extConsLblChildrenRemoveFromConfigDependencyWithL3extOut, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.#", "2"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.#", "2"), - ), - }, - // Update with children first child removed - { - Config: testConfigL3extConsLblChildrenRemoveOneDependencyWithL3extOut, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.#", "1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.#", "1"), - ), - }, - // Update with all children removed - { - Config: testConfigL3extConsLblChildrenRemoveAllDependencyWithL3extOut, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.#", "0"), - resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.#", "0"), - ), - }, }, }) } @@ -209,64 +123,3 @@ resource "aci_l3out_consumer_label" "test" { tag = "yellow-green" } ` -const testConfigL3extConsLblChildrenDependencyWithL3extOut = testConfigL3extOutMin + ` -resource "aci_l3out_consumer_label" "test" { - parent_dn = aci_l3_outside.test.id - name = "test_name" - annotations = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigL3extConsLblChildrenRemoveFromConfigDependencyWithL3extOut = testConfigL3extOutMin + ` -resource "aci_l3out_consumer_label" "test" { - parent_dn = aci_l3_outside.test.id - name = "test_name" -} -` - -const testConfigL3extConsLblChildrenRemoveOneDependencyWithL3extOut = testConfigL3extOutMin + ` -resource "aci_l3out_consumer_label" "test" { - parent_dn = aci_l3_outside.test.id - name = "test_name" - annotations = [ - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigL3extConsLblChildrenRemoveAllDependencyWithL3extOut = testConfigL3extOutMin + ` -resource "aci_l3out_consumer_label" "test" { - parent_dn = aci_l3_outside.test.id - name = "test_name" - annotations = [] - tags = [] -} -` diff --git a/internal/provider/resource_aci_l3out_redistribute_policy.go b/internal/provider/resource_aci_l3out_redistribute_policy.go index ef24891e9..6abda8063 100644 --- a/internal/provider/resource_aci_l3out_redistribute_policy.go +++ b/internal/provider/resource_aci_l3out_redistribute_policy.go @@ -14,13 +14,11 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -49,42 +47,6 @@ type L3extRsRedistributePolResourceModel struct { Annotation types.String `tfsdk:"annotation"` Src types.String `tfsdk:"source"` TnRtctrlProfileName types.String `tfsdk:"route_control_profile_name"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` -} - -// TagAnnotationL3extRsRedistributePolResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationL3extRsRedistributePolResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationL3extRsRedistributePolResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationL3extRsRedistributePolResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationL3extRsRedistributePolResourceModelAttributeTypes()) -} - -// TagTagL3extRsRedistributePolResourceModel describes the resource data model for the children without relation ships. -type TagTagL3extRsRedistributePolResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagL3extRsRedistributePolResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagL3extRsRedistributePolResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagL3extRsRedistributePolResourceModelAttributeTypes()) } type L3extRsRedistributePolIdentifier struct { @@ -151,62 +113,6 @@ func (r *L3extRsRedistributePolResource) Schema(ctx context.Context, req resourc }, MarkdownDescription: `The name of the Route Control Profile object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of resource: aci_l3out_redistribute_policy") @@ -236,11 +142,6 @@ func (r *L3extRsRedistributePolResource) Configure(ctx context.Context, req reso func (r *L3extRsRedistributePolResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_l3out_redistribute_policy") - // On create retrieve information on current state prior to making any changes in order to determine child delete operations - var stateData *L3extRsRedistributePolResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) - setL3extRsRedistributePolId(ctx, stateData) - getAndSetL3extRsRedistributePolAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *L3extRsRedistributePolResourceModel @@ -255,13 +156,7 @@ func (r *L3extRsRedistributePolResource) Create(ctx context.Context, req resourc tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_l3out_redistribute_policy with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsRedistributePolResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagL3extRsRedistributePolResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getL3extRsRedistributePolCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getL3extRsRedistributePolCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -308,11 +203,9 @@ func (r *L3extRsRedistributePolResource) Read(ctx context.Context, req resource. func (r *L3extRsRedistributePolResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_l3out_redistribute_policy") var data *L3extRsRedistributePolResourceModel - var stateData *L3extRsRedistributePolResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -320,13 +213,7 @@ func (r *L3extRsRedistributePolResource) Update(ctx context.Context, req resourc tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_l3out_redistribute_policy with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsRedistributePolResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagL3extRsRedistributePolResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getL3extRsRedistributePolCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getL3extRsRedistributePolCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -380,7 +267,7 @@ func (r *L3extRsRedistributePolResource) ImportState(ctx context.Context, req re } func getAndSetL3extRsRedistributePolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *L3extRsRedistributePolResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "l3extRsRedistributePol,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -413,47 +300,6 @@ func getAndSetL3extRsRedistributePolAttributes(ctx context.Context, diags *diag. if data.TnRtctrlProfileName.IsUnknown() { data.TnRtctrlProfileName = types.StringNull() } - TagAnnotationL3extRsRedistributePol := TagAnnotationL3extRsRedistributePolResourceModel{} - TagAnnotationL3extRsRedistributePolList := make([]TagAnnotationL3extRsRedistributePolResourceModel, 0) - TagTagL3extRsRedistributePol := TagTagL3extRsRedistributePolResourceModel{} - TagTagL3extRsRedistributePolList := make([]TagTagL3extRsRedistributePolResourceModel, 0) - _, ok := classReadInfo[0].(map[string]interface{})["children"] - if ok { - children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) - for _, child := range children { - for childClassName, childClassDetails := range child.(map[string]interface{}) { - childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) - if childClassName == "tagAnnotation" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagAnnotationL3extRsRedistributePol.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationL3extRsRedistributePol.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagAnnotationL3extRsRedistributePolList = append(TagAnnotationL3extRsRedistributePolList, TagAnnotationL3extRsRedistributePol) - } - if childClassName == "tagTag" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagTagL3extRsRedistributePol.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagL3extRsRedistributePol.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagTagL3extRsRedistributePolList = append(TagTagL3extRsRedistributePolList, TagTagL3extRsRedistributePol) - } - } - } - } - tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationL3extRsRedistributePolList) - data.TagAnnotation = tagAnnotationSet - tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagL3extRsRedistributePolList) - data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -496,102 +342,9 @@ func setL3extRsRedistributePolId(ctx context.Context, data *L3extRsRedistributeP data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getL3extRsRedistributePolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagAnnotationL3extRsRedistributePolPlan, tagAnnotationL3extRsRedistributePolState []TagAnnotationL3extRsRedistributePolResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { - tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotationL3extRsRedistributePol := range tagAnnotationL3extRsRedistributePolPlan { - if !tagAnnotationL3extRsRedistributePol.Key.IsNull() && !tagAnnotationL3extRsRedistributePol.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotationL3extRsRedistributePol.Key.ValueString() - } - if !tagAnnotationL3extRsRedistributePol.Value.IsNull() && !tagAnnotationL3extRsRedistributePol.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotationL3extRsRedistributePol.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) - tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotationL3extRsRedistributePol.Key - tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) - } - for _, tagAnnotation := range tagAnnotationL3extRsRedistributePolState { - delete := true - for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { - if tagAnnotationIdentifier.Key == tagAnnotation.Key { - delete = false - break - } - } - if delete { - tagAnnotationChildMapForDelete := NewAciObject() - tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" - tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) - } - } - } else { - data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) - } - - return childPayloads -} - -func getL3extRsRedistributePolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagTagL3extRsRedistributePolPlan, tagTagL3extRsRedistributePolState []TagTagL3extRsRedistributePolResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { - tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTagL3extRsRedistributePol := range tagTagL3extRsRedistributePolPlan { - if !tagTagL3extRsRedistributePol.Key.IsNull() && !tagTagL3extRsRedistributePol.Key.IsUnknown() { - childMap.Attributes["key"] = tagTagL3extRsRedistributePol.Key.ValueString() - } - if !tagTagL3extRsRedistributePol.Value.IsNull() && !tagTagL3extRsRedistributePol.Value.IsUnknown() { - childMap.Attributes["value"] = tagTagL3extRsRedistributePol.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) - tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTagL3extRsRedistributePol.Key - tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) - } - for _, tagTag := range tagTagL3extRsRedistributePolState { - delete := true - for _, tagTagIdentifier := range tagTagIdentifiers { - if tagTagIdentifier.Key == tagTag.Key { - delete = false - break - } - } - if delete { - tagTagChildMapForDelete := NewAciObject() - tagTagChildMapForDelete.Attributes["status"] = "deleted" - tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) - } - } - } else { - data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) - } - - return childPayloads -} - -func getL3extRsRedistributePolCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsRedistributePolResourceModel, tagTagPlan, tagTagState []TagTagL3extRsRedistributePolResourceModel) *container.Container { +func getL3extRsRedistributePolCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} - childPayloads := []map[string]interface{}{} - - TagAnnotationchildPayloads := getL3extRsRedistributePolTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) - if TagAnnotationchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagAnnotationchildPayloads...) - - TagTagchildPayloads := getL3extRsRedistributePolTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) - if TagTagchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagTagchildPayloads...) - - payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_l3out_redistribute_policy_test.go b/internal/provider/resource_aci_l3out_redistribute_policy_test.go index dae8b08af..5acd30270 100644 --- a/internal/provider/resource_aci_l3out_redistribute_policy_test.go +++ b/internal/provider/resource_aci_l3out_redistribute_policy_test.go @@ -66,82 +66,6 @@ func TestAccResourceL3extRsRedistributePolWithL3extOut(t *testing.T) { resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotation", "orchestrator:terraform"), ), }, - // Update with children - { - Config: testConfigL3extRsRedistributePolChildrenDependencyWithL3extOut, - ExpectNonEmptyPlan: true, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "route_control_profile_name", "test_tn_rtctrl_profile_name"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "source", "direct"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.1.value", "value_2"), - ), - }, - // Import testing with children - { - ResourceName: "aci_l3out_redistribute_policy.test", - ImportState: true, - ImportStateVerify: true, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "route_control_profile_name", "test_tn_rtctrl_profile_name"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "source", "direct"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.1.value", "value_2"), - ), - }, - // Update with children removed from config - { - Config: testConfigL3extRsRedistributePolChildrenRemoveFromConfigDependencyWithL3extOut, - ExpectNonEmptyPlan: true, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.#", "2"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.#", "2"), - ), - }, - // Update with children first child removed - { - Config: testConfigL3extRsRedistributePolChildrenRemoveOneDependencyWithL3extOut, - ExpectNonEmptyPlan: true, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.#", "1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.#", "1"), - ), - }, - // Update with all children removed - { - Config: testConfigL3extRsRedistributePolChildrenRemoveAllDependencyWithL3extOut, - ExpectNonEmptyPlan: true, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.#", "0"), - resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.#", "0"), - ), - }, }, }) } @@ -171,68 +95,3 @@ resource "aci_l3out_redistribute_policy" "test" { source = "direct" } ` -const testConfigL3extRsRedistributePolChildrenDependencyWithL3extOut = testConfigL3extOutMinDependencyWithFvTenant + ` -resource "aci_l3out_redistribute_policy" "test" { - parent_dn = aci_l3_outside.test.id - route_control_profile_name = "test_tn_rtctrl_profile_name" - source = "direct" - annotations = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigL3extRsRedistributePolChildrenRemoveFromConfigDependencyWithL3extOut = testConfigL3extOutMinDependencyWithFvTenant + ` -resource "aci_l3out_redistribute_policy" "test" { - parent_dn = aci_l3_outside.test.id - route_control_profile_name = "test_tn_rtctrl_profile_name" - source = "direct" -} -` - -const testConfigL3extRsRedistributePolChildrenRemoveOneDependencyWithL3extOut = testConfigL3extOutMinDependencyWithFvTenant + ` -resource "aci_l3out_redistribute_policy" "test" { - parent_dn = aci_l3_outside.test.id - route_control_profile_name = "test_tn_rtctrl_profile_name" - source = "direct" - annotations = [ - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigL3extRsRedistributePolChildrenRemoveAllDependencyWithL3extOut = testConfigL3extOutMinDependencyWithFvTenant + ` -resource "aci_l3out_redistribute_policy" "test" { - parent_dn = aci_l3_outside.test.id - route_control_profile_name = "test_tn_rtctrl_profile_name" - source = "direct" - annotations = [] - tags = [] -} -` diff --git a/internal/provider/resource_aci_out_of_band_contract.go b/internal/provider/resource_aci_out_of_band_contract.go index 5639d94fd..62b6ed3a4 100644 --- a/internal/provider/resource_aci_out_of_band_contract.go +++ b/internal/provider/resource_aci_out_of_band_contract.go @@ -14,13 +14,11 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -44,53 +42,17 @@ type VzOOBBrCPResource struct { // VzOOBBrCPResourceModel describes the resource data model. type VzOOBBrCPResourceModel struct { - Id types.String `tfsdk:"id"` - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Intent types.String `tfsdk:"intent"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - OwnerKey types.String `tfsdk:"owner_key"` - OwnerTag types.String `tfsdk:"owner_tag"` - Prio types.String `tfsdk:"priority"` - Scope types.String `tfsdk:"scope"` - TargetDscp types.String `tfsdk:"target_dscp"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` -} - -// TagAnnotationVzOOBBrCPResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationVzOOBBrCPResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationVzOOBBrCPResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationVzOOBBrCPResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationVzOOBBrCPResourceModelAttributeTypes()) -} - -// TagTagVzOOBBrCPResourceModel describes the resource data model for the children without relation ships. -type TagTagVzOOBBrCPResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagVzOOBBrCPResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagVzOOBBrCPResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagVzOOBBrCPResourceModelAttributeTypes()) + Id types.String `tfsdk:"id"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Intent types.String `tfsdk:"intent"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + OwnerKey types.String `tfsdk:"owner_key"` + OwnerTag types.String `tfsdk:"owner_tag"` + Prio types.String `tfsdk:"priority"` + Scope types.String `tfsdk:"scope"` + TargetDscp types.String `tfsdk:"target_dscp"` } type VzOOBBrCPIdentifier struct { @@ -220,62 +182,6 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque }, MarkdownDescription: `The target DSCP value of the Out Of Band Contract object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of resource: aci_out_of_band_contract") @@ -305,11 +211,6 @@ func (r *VzOOBBrCPResource) Configure(ctx context.Context, req resource.Configur func (r *VzOOBBrCPResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_out_of_band_contract") - // On create retrieve information on current state prior to making any changes in order to determine child delete operations - var stateData *VzOOBBrCPResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) - setVzOOBBrCPId(ctx, stateData) - getAndSetVzOOBBrCPAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *VzOOBBrCPResourceModel @@ -324,13 +225,7 @@ func (r *VzOOBBrCPResource) Create(ctx context.Context, req resource.CreateReque tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_out_of_band_contract with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationVzOOBBrCPResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagVzOOBBrCPResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getVzOOBBrCPCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getVzOOBBrCPCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -377,11 +272,9 @@ func (r *VzOOBBrCPResource) Read(ctx context.Context, req resource.ReadRequest, func (r *VzOOBBrCPResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_out_of_band_contract") var data *VzOOBBrCPResourceModel - var stateData *VzOOBBrCPResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -389,13 +282,7 @@ func (r *VzOOBBrCPResource) Update(ctx context.Context, req resource.UpdateReque tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_out_of_band_contract with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationVzOOBBrCPResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagVzOOBBrCPResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getVzOOBBrCPCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getVzOOBBrCPCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -449,7 +336,7 @@ func (r *VzOOBBrCPResource) ImportState(ctx context.Context, req resource.Import } func getAndSetVzOOBBrCPAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *VzOOBBrCPResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "vzOOBBrCP,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -523,47 +410,6 @@ func getAndSetVzOOBBrCPAttributes(ctx context.Context, diags *diag.Diagnostics, if data.TargetDscp.IsUnknown() { data.TargetDscp = types.StringNull() } - TagAnnotationVzOOBBrCP := TagAnnotationVzOOBBrCPResourceModel{} - TagAnnotationVzOOBBrCPList := make([]TagAnnotationVzOOBBrCPResourceModel, 0) - TagTagVzOOBBrCP := TagTagVzOOBBrCPResourceModel{} - TagTagVzOOBBrCPList := make([]TagTagVzOOBBrCPResourceModel, 0) - _, ok := classReadInfo[0].(map[string]interface{})["children"] - if ok { - children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) - for _, child := range children { - for childClassName, childClassDetails := range child.(map[string]interface{}) { - childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) - if childClassName == "tagAnnotation" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagAnnotationVzOOBBrCP.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationVzOOBBrCP.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagAnnotationVzOOBBrCPList = append(TagAnnotationVzOOBBrCPList, TagAnnotationVzOOBBrCP) - } - if childClassName == "tagTag" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagTagVzOOBBrCP.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagVzOOBBrCP.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagTagVzOOBBrCPList = append(TagTagVzOOBBrCPList, TagTagVzOOBBrCP) - } - } - } - } - tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationVzOOBBrCPList) - data.TagAnnotation = tagAnnotationSet - tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagVzOOBBrCPList) - data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -590,102 +436,9 @@ func setVzOOBBrCPId(ctx context.Context, data *VzOOBBrCPResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", strings.Split([]string{"uni/tn-mgmt/oobbrc-{name}"}[0], "/")[0], rn)) } -func getVzOOBBrCPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagAnnotationVzOOBBrCPPlan, tagAnnotationVzOOBBrCPState []TagAnnotationVzOOBBrCPResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { - tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotationVzOOBBrCP := range tagAnnotationVzOOBBrCPPlan { - if !tagAnnotationVzOOBBrCP.Key.IsNull() && !tagAnnotationVzOOBBrCP.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotationVzOOBBrCP.Key.ValueString() - } - if !tagAnnotationVzOOBBrCP.Value.IsNull() && !tagAnnotationVzOOBBrCP.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotationVzOOBBrCP.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) - tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotationVzOOBBrCP.Key - tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) - } - for _, tagAnnotation := range tagAnnotationVzOOBBrCPState { - delete := true - for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { - if tagAnnotationIdentifier.Key == tagAnnotation.Key { - delete = false - break - } - } - if delete { - tagAnnotationChildMapForDelete := NewAciObject() - tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" - tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) - } - } - } else { - data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) - } - - return childPayloads -} - -func getVzOOBBrCPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagTagVzOOBBrCPPlan, tagTagVzOOBBrCPState []TagTagVzOOBBrCPResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { - tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTagVzOOBBrCP := range tagTagVzOOBBrCPPlan { - if !tagTagVzOOBBrCP.Key.IsNull() && !tagTagVzOOBBrCP.Key.IsUnknown() { - childMap.Attributes["key"] = tagTagVzOOBBrCP.Key.ValueString() - } - if !tagTagVzOOBBrCP.Value.IsNull() && !tagTagVzOOBBrCP.Value.IsUnknown() { - childMap.Attributes["value"] = tagTagVzOOBBrCP.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) - tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTagVzOOBBrCP.Key - tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) - } - for _, tagTag := range tagTagVzOOBBrCPState { - delete := true - for _, tagTagIdentifier := range tagTagIdentifiers { - if tagTagIdentifier.Key == tagTag.Key { - delete = false - break - } - } - if delete { - tagTagChildMapForDelete := NewAciObject() - tagTagChildMapForDelete.Attributes["status"] = "deleted" - tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) - } - } - } else { - data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) - } - - return childPayloads -} - -func getVzOOBBrCPCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationVzOOBBrCPResourceModel, tagTagPlan, tagTagState []TagTagVzOOBBrCPResourceModel) *container.Container { +func getVzOOBBrCPCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} - childPayloads := []map[string]interface{}{} - - TagAnnotationchildPayloads := getVzOOBBrCPTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) - if TagAnnotationchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagAnnotationchildPayloads...) - - TagTagchildPayloads := getVzOOBBrCPTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) - if TagTagchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagTagchildPayloads...) - - payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_out_of_band_contract_test.go b/internal/provider/resource_aci_out_of_band_contract_test.go index baabe7f5c..da850a413 100644 --- a/internal/provider/resource_aci_out_of_band_contract_test.go +++ b/internal/provider/resource_aci_out_of_band_contract_test.go @@ -98,94 +98,6 @@ func TestAccResourceVzOOBBrCP(t *testing.T) { resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "target_dscp", "unspecified"), ), }, - // Update with children - { - Config: testConfigVzOOBBrCPChildren, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "description", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "intent", "install"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_key", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_tag", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "priority", "unspecified"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "scope", "context"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "target_dscp", "unspecified"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.#", "2"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.#", "2"), - ), - }, - // Update with children removed from config - { - Config: testConfigVzOOBBrCPChildrenRemoveFromConfig, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "description", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "intent", "install"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_key", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_tag", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "priority", "unspecified"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "scope", "context"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "target_dscp", "unspecified"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.#", "2"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.#", "2"), - ), - }, - // Update with children first child removed - { - Config: testConfigVzOOBBrCPChildrenRemoveOne, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "description", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "intent", "install"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_key", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_tag", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "priority", "unspecified"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "scope", "context"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "target_dscp", "unspecified"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.#", "1"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.#", "1"), - ), - }, - // Update with all children removed - { - Config: testConfigVzOOBBrCPChildrenRemoveAll, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "description", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "intent", "install"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_key", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_tag", ""), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "priority", "unspecified"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "scope", "context"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "target_dscp", "unspecified"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.#", "0"), - resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.#", "0"), - ), - }, }, }) } @@ -225,60 +137,3 @@ resource "aci_out_of_band_contract" "test" { target_dscp = "unspecified" } ` -const testConfigVzOOBBrCPChildren = ` -resource "aci_out_of_band_contract" "test" { - name = "test_name" - annotations = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigVzOOBBrCPChildrenRemoveFromConfig = ` -resource "aci_out_of_band_contract" "test" { - name = "test_name" -} -` - -const testConfigVzOOBBrCPChildrenRemoveOne = ` -resource "aci_out_of_band_contract" "test" { - name = "test_name" - annotations = [ - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigVzOOBBrCPChildrenRemoveAll = ` -resource "aci_out_of_band_contract" "test" { - name = "test_name" - annotations = [] - tags = [] -} -` diff --git a/internal/provider/resource_aci_pim_route_map_entry.go b/internal/provider/resource_aci_pim_route_map_entry.go index 8870151d0..d508b7290 100644 --- a/internal/provider/resource_aci_pim_route_map_entry.go +++ b/internal/provider/resource_aci_pim_route_map_entry.go @@ -14,13 +14,11 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -44,53 +42,17 @@ type PimRouteMapEntryResource struct { // PimRouteMapEntryResourceModel describes the resource data model. type PimRouteMapEntryResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Action types.String `tfsdk:"action"` - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Grp types.String `tfsdk:"group_ip"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - Order types.String `tfsdk:"order"` - Rp types.String `tfsdk:"rendezvous_point_ip"` - Src types.String `tfsdk:"source_ip"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` -} - -// TagAnnotationPimRouteMapEntryResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationPimRouteMapEntryResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationPimRouteMapEntryResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationPimRouteMapEntryResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationPimRouteMapEntryResourceModelAttributeTypes()) -} - -// TagTagPimRouteMapEntryResourceModel describes the resource data model for the children without relation ships. -type TagTagPimRouteMapEntryResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagPimRouteMapEntryResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagPimRouteMapEntryResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagPimRouteMapEntryResourceModelAttributeTypes()) + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Action types.String `tfsdk:"action"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Grp types.String `tfsdk:"group_ip"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + Order types.String `tfsdk:"order"` + Rp types.String `tfsdk:"rendezvous_point_ip"` + Src types.String `tfsdk:"source_ip"` } type PimRouteMapEntryIdentifier struct { @@ -210,62 +172,6 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche }, MarkdownDescription: `The source ip of the Pim Route Map Entry object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of resource: aci_pim_route_map_entry") @@ -295,11 +201,6 @@ func (r *PimRouteMapEntryResource) Configure(ctx context.Context, req resource.C func (r *PimRouteMapEntryResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_pim_route_map_entry") - // On create retrieve information on current state prior to making any changes in order to determine child delete operations - var stateData *PimRouteMapEntryResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) - setPimRouteMapEntryId(ctx, stateData) - getAndSetPimRouteMapEntryAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *PimRouteMapEntryResourceModel @@ -314,13 +215,7 @@ func (r *PimRouteMapEntryResource) Create(ctx context.Context, req resource.Crea tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_pim_route_map_entry with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapEntryResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagPimRouteMapEntryResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getPimRouteMapEntryCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getPimRouteMapEntryCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -367,11 +262,9 @@ func (r *PimRouteMapEntryResource) Read(ctx context.Context, req resource.ReadRe func (r *PimRouteMapEntryResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_pim_route_map_entry") var data *PimRouteMapEntryResourceModel - var stateData *PimRouteMapEntryResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -379,13 +272,7 @@ func (r *PimRouteMapEntryResource) Update(ctx context.Context, req resource.Upda tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_pim_route_map_entry with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapEntryResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagPimRouteMapEntryResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getPimRouteMapEntryCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getPimRouteMapEntryCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -439,7 +326,7 @@ func (r *PimRouteMapEntryResource) ImportState(ctx context.Context, req resource } func getAndSetPimRouteMapEntryAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *PimRouteMapEntryResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "pimRouteMapEntry,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -508,47 +395,6 @@ func getAndSetPimRouteMapEntryAttributes(ctx context.Context, diags *diag.Diagno if data.Src.IsUnknown() { data.Src = types.StringNull() } - TagAnnotationPimRouteMapEntry := TagAnnotationPimRouteMapEntryResourceModel{} - TagAnnotationPimRouteMapEntryList := make([]TagAnnotationPimRouteMapEntryResourceModel, 0) - TagTagPimRouteMapEntry := TagTagPimRouteMapEntryResourceModel{} - TagTagPimRouteMapEntryList := make([]TagTagPimRouteMapEntryResourceModel, 0) - _, ok := classReadInfo[0].(map[string]interface{})["children"] - if ok { - children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) - for _, child := range children { - for childClassName, childClassDetails := range child.(map[string]interface{}) { - childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) - if childClassName == "tagAnnotation" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagAnnotationPimRouteMapEntry.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationPimRouteMapEntry.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagAnnotationPimRouteMapEntryList = append(TagAnnotationPimRouteMapEntryList, TagAnnotationPimRouteMapEntry) - } - if childClassName == "tagTag" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagTagPimRouteMapEntry.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagPimRouteMapEntry.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagTagPimRouteMapEntryList = append(TagTagPimRouteMapEntryList, TagTagPimRouteMapEntry) - } - } - } - } - tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationPimRouteMapEntryList) - data.TagAnnotation = tagAnnotationSet - tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagPimRouteMapEntryList) - data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -591,102 +437,9 @@ func setPimRouteMapEntryId(ctx context.Context, data *PimRouteMapEntryResourceMo data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getPimRouteMapEntryTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagAnnotationPimRouteMapEntryPlan, tagAnnotationPimRouteMapEntryState []TagAnnotationPimRouteMapEntryResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { - tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotationPimRouteMapEntry := range tagAnnotationPimRouteMapEntryPlan { - if !tagAnnotationPimRouteMapEntry.Key.IsNull() && !tagAnnotationPimRouteMapEntry.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotationPimRouteMapEntry.Key.ValueString() - } - if !tagAnnotationPimRouteMapEntry.Value.IsNull() && !tagAnnotationPimRouteMapEntry.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotationPimRouteMapEntry.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) - tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotationPimRouteMapEntry.Key - tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) - } - for _, tagAnnotation := range tagAnnotationPimRouteMapEntryState { - delete := true - for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { - if tagAnnotationIdentifier.Key == tagAnnotation.Key { - delete = false - break - } - } - if delete { - tagAnnotationChildMapForDelete := NewAciObject() - tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" - tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) - } - } - } else { - data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) - } - - return childPayloads -} - -func getPimRouteMapEntryTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagTagPimRouteMapEntryPlan, tagTagPimRouteMapEntryState []TagTagPimRouteMapEntryResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { - tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTagPimRouteMapEntry := range tagTagPimRouteMapEntryPlan { - if !tagTagPimRouteMapEntry.Key.IsNull() && !tagTagPimRouteMapEntry.Key.IsUnknown() { - childMap.Attributes["key"] = tagTagPimRouteMapEntry.Key.ValueString() - } - if !tagTagPimRouteMapEntry.Value.IsNull() && !tagTagPimRouteMapEntry.Value.IsUnknown() { - childMap.Attributes["value"] = tagTagPimRouteMapEntry.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) - tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTagPimRouteMapEntry.Key - tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) - } - for _, tagTag := range tagTagPimRouteMapEntryState { - delete := true - for _, tagTagIdentifier := range tagTagIdentifiers { - if tagTagIdentifier.Key == tagTag.Key { - delete = false - break - } - } - if delete { - tagTagChildMapForDelete := NewAciObject() - tagTagChildMapForDelete.Attributes["status"] = "deleted" - tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) - } - } - } else { - data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) - } - - return childPayloads -} - -func getPimRouteMapEntryCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapEntryResourceModel, tagTagPlan, tagTagState []TagTagPimRouteMapEntryResourceModel) *container.Container { +func getPimRouteMapEntryCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} - childPayloads := []map[string]interface{}{} - - TagAnnotationchildPayloads := getPimRouteMapEntryTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) - if TagAnnotationchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagAnnotationchildPayloads...) - - TagTagchildPayloads := getPimRouteMapEntryTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) - if TagTagchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagTagchildPayloads...) - - payloadMap["children"] = childPayloads if !data.Action.IsNull() && !data.Action.IsUnknown() { payloadMap["attributes"].(map[string]string)["action"] = data.Action.ValueString() } diff --git a/internal/provider/resource_aci_pim_route_map_entry_test.go b/internal/provider/resource_aci_pim_route_map_entry_test.go index 162dade9a..f9f5eeaf5 100644 --- a/internal/provider/resource_aci_pim_route_map_entry_test.go +++ b/internal/provider/resource_aci_pim_route_map_entry_test.go @@ -89,94 +89,6 @@ func TestAccResourcePimRouteMapEntryWithPimRouteMapPol(t *testing.T) { resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "source_ip", "0.0.0.0"), ), }, - // Update with children - { - Config: testConfigPimRouteMapEntryChildrenDependencyWithPimRouteMapPol, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "order", "1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "action", "permit"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "description", ""), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "group_ip", "0.0.0.0"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "name", ""), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "rendezvous_point_ip", "0.0.0.0"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "source_ip", "0.0.0.0"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.1.value", "value_2"), - ), - }, - // Import testing with children - { - ResourceName: "aci_pim_route_map_entry.test", - ImportState: true, - ImportStateVerify: true, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "order", "1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "action", "permit"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "description", ""), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "group_ip", "0.0.0.0"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "name", ""), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "rendezvous_point_ip", "0.0.0.0"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "source_ip", "0.0.0.0"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.1.value", "value_2"), - ), - }, - // Update with children removed from config - { - Config: testConfigPimRouteMapEntryChildrenRemoveFromConfigDependencyWithPimRouteMapPol, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.#", "2"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.#", "2"), - ), - }, - // Update with children first child removed - { - Config: testConfigPimRouteMapEntryChildrenRemoveOneDependencyWithPimRouteMapPol, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.#", "1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.#", "1"), - ), - }, - // Update with all children removed - { - Config: testConfigPimRouteMapEntryChildrenRemoveAllDependencyWithPimRouteMapPol, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.#", "0"), - resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.#", "0"), - ), - }, }, }) } @@ -217,64 +129,3 @@ resource "aci_pim_route_map_entry" "test" { source_ip = "0.0.0.0" } ` -const testConfigPimRouteMapEntryChildrenDependencyWithPimRouteMapPol = testConfigPimRouteMapPolMinDependencyWithFvTenant + ` -resource "aci_pim_route_map_entry" "test" { - parent_dn = aci_pim_route_map_policy.test.id - order = "1" - annotations = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigPimRouteMapEntryChildrenRemoveFromConfigDependencyWithPimRouteMapPol = testConfigPimRouteMapPolMinDependencyWithFvTenant + ` -resource "aci_pim_route_map_entry" "test" { - parent_dn = aci_pim_route_map_policy.test.id - order = "1" -} -` - -const testConfigPimRouteMapEntryChildrenRemoveOneDependencyWithPimRouteMapPol = testConfigPimRouteMapPolMinDependencyWithFvTenant + ` -resource "aci_pim_route_map_entry" "test" { - parent_dn = aci_pim_route_map_policy.test.id - order = "1" - annotations = [ - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigPimRouteMapEntryChildrenRemoveAllDependencyWithPimRouteMapPol = testConfigPimRouteMapPolMinDependencyWithFvTenant + ` -resource "aci_pim_route_map_entry" "test" { - parent_dn = aci_pim_route_map_policy.test.id - order = "1" - annotations = [] - tags = [] -} -` diff --git a/internal/provider/resource_aci_pim_route_map_policy.go b/internal/provider/resource_aci_pim_route_map_policy.go index b925b928e..f34c42edf 100644 --- a/internal/provider/resource_aci_pim_route_map_policy.go +++ b/internal/provider/resource_aci_pim_route_map_policy.go @@ -13,13 +13,11 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" @@ -42,50 +40,14 @@ type PimRouteMapPolResource struct { // PimRouteMapPolResourceModel describes the resource data model. type PimRouteMapPolResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - OwnerKey types.String `tfsdk:"owner_key"` - OwnerTag types.String `tfsdk:"owner_tag"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` -} - -// TagAnnotationPimRouteMapPolResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationPimRouteMapPolResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationPimRouteMapPolResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationPimRouteMapPolResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationPimRouteMapPolResourceModelAttributeTypes()) -} - -// TagTagPimRouteMapPolResourceModel describes the resource data model for the children without relation ships. -type TagTagPimRouteMapPolResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagPimRouteMapPolResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagPimRouteMapPolResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagPimRouteMapPolResourceModelAttributeTypes()) + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + OwnerKey types.String `tfsdk:"owner_key"` + OwnerTag types.String `tfsdk:"owner_tag"` } type PimRouteMapPolIdentifier struct { @@ -175,62 +137,6 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema }, MarkdownDescription: `A tag for enabling clients to add their own data. For example, to indicate who created this object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of resource: aci_pim_route_map_policy") @@ -260,11 +166,6 @@ func (r *PimRouteMapPolResource) Configure(ctx context.Context, req resource.Con func (r *PimRouteMapPolResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_pim_route_map_policy") - // On create retrieve information on current state prior to making any changes in order to determine child delete operations - var stateData *PimRouteMapPolResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) - setPimRouteMapPolId(ctx, stateData) - getAndSetPimRouteMapPolAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *PimRouteMapPolResourceModel @@ -279,13 +180,7 @@ func (r *PimRouteMapPolResource) Create(ctx context.Context, req resource.Create tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_pim_route_map_policy with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapPolResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagPimRouteMapPolResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getPimRouteMapPolCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getPimRouteMapPolCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -332,11 +227,9 @@ func (r *PimRouteMapPolResource) Read(ctx context.Context, req resource.ReadRequ func (r *PimRouteMapPolResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_pim_route_map_policy") var data *PimRouteMapPolResourceModel - var stateData *PimRouteMapPolResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -344,13 +237,7 @@ func (r *PimRouteMapPolResource) Update(ctx context.Context, req resource.Update tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_pim_route_map_policy with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapPolResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagPimRouteMapPolResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getPimRouteMapPolCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getPimRouteMapPolCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -404,7 +291,7 @@ func (r *PimRouteMapPolResource) ImportState(ctx context.Context, req resource.I } func getAndSetPimRouteMapPolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *PimRouteMapPolResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "pimRouteMapPol,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -455,47 +342,6 @@ func getAndSetPimRouteMapPolAttributes(ctx context.Context, diags *diag.Diagnost if data.OwnerTag.IsUnknown() { data.OwnerTag = types.StringNull() } - TagAnnotationPimRouteMapPol := TagAnnotationPimRouteMapPolResourceModel{} - TagAnnotationPimRouteMapPolList := make([]TagAnnotationPimRouteMapPolResourceModel, 0) - TagTagPimRouteMapPol := TagTagPimRouteMapPolResourceModel{} - TagTagPimRouteMapPolList := make([]TagTagPimRouteMapPolResourceModel, 0) - _, ok := classReadInfo[0].(map[string]interface{})["children"] - if ok { - children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) - for _, child := range children { - for childClassName, childClassDetails := range child.(map[string]interface{}) { - childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) - if childClassName == "tagAnnotation" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagAnnotationPimRouteMapPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationPimRouteMapPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagAnnotationPimRouteMapPolList = append(TagAnnotationPimRouteMapPolList, TagAnnotationPimRouteMapPol) - } - if childClassName == "tagTag" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagTagPimRouteMapPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagPimRouteMapPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagTagPimRouteMapPolList = append(TagTagPimRouteMapPolList, TagTagPimRouteMapPol) - } - } - } - } - tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationPimRouteMapPolList) - data.TagAnnotation = tagAnnotationSet - tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagPimRouteMapPolList) - data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -538,102 +384,9 @@ func setPimRouteMapPolId(ctx context.Context, data *PimRouteMapPolResourceModel) data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getPimRouteMapPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagAnnotationPimRouteMapPolPlan, tagAnnotationPimRouteMapPolState []TagAnnotationPimRouteMapPolResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { - tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotationPimRouteMapPol := range tagAnnotationPimRouteMapPolPlan { - if !tagAnnotationPimRouteMapPol.Key.IsNull() && !tagAnnotationPimRouteMapPol.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotationPimRouteMapPol.Key.ValueString() - } - if !tagAnnotationPimRouteMapPol.Value.IsNull() && !tagAnnotationPimRouteMapPol.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotationPimRouteMapPol.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) - tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotationPimRouteMapPol.Key - tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) - } - for _, tagAnnotation := range tagAnnotationPimRouteMapPolState { - delete := true - for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { - if tagAnnotationIdentifier.Key == tagAnnotation.Key { - delete = false - break - } - } - if delete { - tagAnnotationChildMapForDelete := NewAciObject() - tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" - tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) - } - } - } else { - data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) - } - - return childPayloads -} - -func getPimRouteMapPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagTagPimRouteMapPolPlan, tagTagPimRouteMapPolState []TagTagPimRouteMapPolResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { - tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTagPimRouteMapPol := range tagTagPimRouteMapPolPlan { - if !tagTagPimRouteMapPol.Key.IsNull() && !tagTagPimRouteMapPol.Key.IsUnknown() { - childMap.Attributes["key"] = tagTagPimRouteMapPol.Key.ValueString() - } - if !tagTagPimRouteMapPol.Value.IsNull() && !tagTagPimRouteMapPol.Value.IsUnknown() { - childMap.Attributes["value"] = tagTagPimRouteMapPol.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) - tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTagPimRouteMapPol.Key - tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) - } - for _, tagTag := range tagTagPimRouteMapPolState { - delete := true - for _, tagTagIdentifier := range tagTagIdentifiers { - if tagTagIdentifier.Key == tagTag.Key { - delete = false - break - } - } - if delete { - tagTagChildMapForDelete := NewAciObject() - tagTagChildMapForDelete.Attributes["status"] = "deleted" - tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) - } - } - } else { - data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) - } - - return childPayloads -} - -func getPimRouteMapPolCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapPolResourceModel, tagTagPlan, tagTagState []TagTagPimRouteMapPolResourceModel) *container.Container { +func getPimRouteMapPolCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} - childPayloads := []map[string]interface{}{} - - TagAnnotationchildPayloads := getPimRouteMapPolTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) - if TagAnnotationchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagAnnotationchildPayloads...) - - TagTagchildPayloads := getPimRouteMapPolTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) - if TagTagchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagTagchildPayloads...) - - payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_pim_route_map_policy_test.go b/internal/provider/resource_aci_pim_route_map_policy_test.go index aff79ff65..b3103eca3 100644 --- a/internal/provider/resource_aci_pim_route_map_policy_test.go +++ b/internal/provider/resource_aci_pim_route_map_policy_test.go @@ -77,88 +77,6 @@ func TestAccResourcePimRouteMapPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "owner_tag", ""), ), }, - // Update with children - { - Config: testConfigPimRouteMapPolChildrenDependencyWithFvTenant, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "name", "test_name"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "description", ""), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "owner_key", ""), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "owner_tag", ""), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.1.value", "value_2"), - ), - }, - // Import testing with children - { - ResourceName: "aci_pim_route_map_policy.test", - ImportState: true, - ImportStateVerify: true, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "name", "test_name"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "description", ""), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "owner_key", ""), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "owner_tag", ""), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.1.value", "value_2"), - ), - }, - // Update with children removed from config - { - Config: testConfigPimRouteMapPolChildrenRemoveFromConfigDependencyWithFvTenant, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.#", "2"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.#", "2"), - ), - }, - // Update with children first child removed - { - Config: testConfigPimRouteMapPolChildrenRemoveOneDependencyWithFvTenant, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.#", "1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.#", "1"), - ), - }, - // Update with all children removed - { - Config: testConfigPimRouteMapPolChildrenRemoveAllDependencyWithFvTenant, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.#", "0"), - resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.#", "0"), - ), - }, }, }) } @@ -193,64 +111,3 @@ resource "aci_pim_route_map_policy" "test" { owner_tag = "" } ` -const testConfigPimRouteMapPolChildrenDependencyWithFvTenant = testConfigFvTenantMin + ` -resource "aci_pim_route_map_policy" "test" { - parent_dn = aci_tenant.test.id - name = "test_name" - annotations = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigPimRouteMapPolChildrenRemoveFromConfigDependencyWithFvTenant = testConfigFvTenantMin + ` -resource "aci_pim_route_map_policy" "test" { - parent_dn = aci_tenant.test.id - name = "test_name" -} -` - -const testConfigPimRouteMapPolChildrenRemoveOneDependencyWithFvTenant = testConfigFvTenantMin + ` -resource "aci_pim_route_map_policy" "test" { - parent_dn = aci_tenant.test.id - name = "test_name" - annotations = [ - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigPimRouteMapPolChildrenRemoveAllDependencyWithFvTenant = testConfigFvTenantMin + ` -resource "aci_pim_route_map_policy" "test" { - parent_dn = aci_tenant.test.id - name = "test_name" - annotations = [] - tags = [] -} -` diff --git a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go index 29d0237b8..3fee1af19 100644 --- a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go +++ b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go @@ -14,13 +14,11 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -49,42 +47,6 @@ type MgmtRsOoBConsResourceModel struct { Annotation types.String `tfsdk:"annotation"` Prio types.String `tfsdk:"priority"` TnVzOOBBrCPName types.String `tfsdk:"out_of_band_contract_name"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` -} - -// TagAnnotationMgmtRsOoBConsResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationMgmtRsOoBConsResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationMgmtRsOoBConsResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationMgmtRsOoBConsResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtRsOoBConsResourceModelAttributeTypes()) -} - -// TagTagMgmtRsOoBConsResourceModel describes the resource data model for the children without relation ships. -type TagTagMgmtRsOoBConsResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagMgmtRsOoBConsResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagMgmtRsOoBConsResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtRsOoBConsResourceModelAttributeTypes()) } type MgmtRsOoBConsIdentifier struct { @@ -150,62 +112,6 @@ func (r *MgmtRsOoBConsResource) Schema(ctx context.Context, req resource.SchemaR }, MarkdownDescription: `The name of the Out Of Band Contract object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of resource: aci_relation_to_consumed_out_of_band_contract") @@ -235,11 +141,6 @@ func (r *MgmtRsOoBConsResource) Configure(ctx context.Context, req resource.Conf func (r *MgmtRsOoBConsResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_relation_to_consumed_out_of_band_contract") - // On create retrieve information on current state prior to making any changes in order to determine child delete operations - var stateData *MgmtRsOoBConsResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) - setMgmtRsOoBConsId(ctx, stateData) - getAndSetMgmtRsOoBConsAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *MgmtRsOoBConsResourceModel @@ -254,13 +155,7 @@ func (r *MgmtRsOoBConsResource) Create(ctx context.Context, req resource.CreateR tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_relation_to_consumed_out_of_band_contract with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtRsOoBConsResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagMgmtRsOoBConsResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getMgmtRsOoBConsCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getMgmtRsOoBConsCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -307,11 +202,9 @@ func (r *MgmtRsOoBConsResource) Read(ctx context.Context, req resource.ReadReque func (r *MgmtRsOoBConsResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_relation_to_consumed_out_of_band_contract") var data *MgmtRsOoBConsResourceModel - var stateData *MgmtRsOoBConsResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -319,13 +212,7 @@ func (r *MgmtRsOoBConsResource) Update(ctx context.Context, req resource.UpdateR tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_relation_to_consumed_out_of_band_contract with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtRsOoBConsResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagMgmtRsOoBConsResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getMgmtRsOoBConsCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getMgmtRsOoBConsCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -379,7 +266,7 @@ func (r *MgmtRsOoBConsResource) ImportState(ctx context.Context, req resource.Im } func getAndSetMgmtRsOoBConsAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *MgmtRsOoBConsResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtRsOoBCons,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -412,47 +299,6 @@ func getAndSetMgmtRsOoBConsAttributes(ctx context.Context, diags *diag.Diagnosti if data.TnVzOOBBrCPName.IsUnknown() { data.TnVzOOBBrCPName = types.StringNull() } - TagAnnotationMgmtRsOoBCons := TagAnnotationMgmtRsOoBConsResourceModel{} - TagAnnotationMgmtRsOoBConsList := make([]TagAnnotationMgmtRsOoBConsResourceModel, 0) - TagTagMgmtRsOoBCons := TagTagMgmtRsOoBConsResourceModel{} - TagTagMgmtRsOoBConsList := make([]TagTagMgmtRsOoBConsResourceModel, 0) - _, ok := classReadInfo[0].(map[string]interface{})["children"] - if ok { - children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) - for _, child := range children { - for childClassName, childClassDetails := range child.(map[string]interface{}) { - childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) - if childClassName == "tagAnnotation" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagAnnotationMgmtRsOoBCons.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationMgmtRsOoBCons.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagAnnotationMgmtRsOoBConsList = append(TagAnnotationMgmtRsOoBConsList, TagAnnotationMgmtRsOoBCons) - } - if childClassName == "tagTag" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagTagMgmtRsOoBCons.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagMgmtRsOoBCons.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagTagMgmtRsOoBConsList = append(TagTagMgmtRsOoBConsList, TagTagMgmtRsOoBCons) - } - } - } - } - tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationMgmtRsOoBConsList) - data.TagAnnotation = tagAnnotationSet - tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagMgmtRsOoBConsList) - data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -495,102 +341,9 @@ func setMgmtRsOoBConsId(ctx context.Context, data *MgmtRsOoBConsResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getMgmtRsOoBConsTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagAnnotationMgmtRsOoBConsPlan, tagAnnotationMgmtRsOoBConsState []TagAnnotationMgmtRsOoBConsResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { - tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotationMgmtRsOoBCons := range tagAnnotationMgmtRsOoBConsPlan { - if !tagAnnotationMgmtRsOoBCons.Key.IsNull() && !tagAnnotationMgmtRsOoBCons.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotationMgmtRsOoBCons.Key.ValueString() - } - if !tagAnnotationMgmtRsOoBCons.Value.IsNull() && !tagAnnotationMgmtRsOoBCons.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotationMgmtRsOoBCons.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) - tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotationMgmtRsOoBCons.Key - tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) - } - for _, tagAnnotation := range tagAnnotationMgmtRsOoBConsState { - delete := true - for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { - if tagAnnotationIdentifier.Key == tagAnnotation.Key { - delete = false - break - } - } - if delete { - tagAnnotationChildMapForDelete := NewAciObject() - tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" - tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) - } - } - } else { - data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) - } - - return childPayloads -} - -func getMgmtRsOoBConsTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagTagMgmtRsOoBConsPlan, tagTagMgmtRsOoBConsState []TagTagMgmtRsOoBConsResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { - tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTagMgmtRsOoBCons := range tagTagMgmtRsOoBConsPlan { - if !tagTagMgmtRsOoBCons.Key.IsNull() && !tagTagMgmtRsOoBCons.Key.IsUnknown() { - childMap.Attributes["key"] = tagTagMgmtRsOoBCons.Key.ValueString() - } - if !tagTagMgmtRsOoBCons.Value.IsNull() && !tagTagMgmtRsOoBCons.Value.IsUnknown() { - childMap.Attributes["value"] = tagTagMgmtRsOoBCons.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) - tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTagMgmtRsOoBCons.Key - tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) - } - for _, tagTag := range tagTagMgmtRsOoBConsState { - delete := true - for _, tagTagIdentifier := range tagTagIdentifiers { - if tagTagIdentifier.Key == tagTag.Key { - delete = false - break - } - } - if delete { - tagTagChildMapForDelete := NewAciObject() - tagTagChildMapForDelete.Attributes["status"] = "deleted" - tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) - } - } - } else { - data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) - } - - return childPayloads -} - -func getMgmtRsOoBConsCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtRsOoBConsResourceModel, tagTagPlan, tagTagState []TagTagMgmtRsOoBConsResourceModel) *container.Container { +func getMgmtRsOoBConsCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} - childPayloads := []map[string]interface{}{} - - TagAnnotationchildPayloads := getMgmtRsOoBConsTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) - if TagAnnotationchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagAnnotationchildPayloads...) - - TagTagchildPayloads := getMgmtRsOoBConsTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) - if TagTagchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagTagchildPayloads...) - - payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract_test.go b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract_test.go index 14bf7e258..98bbe27b8 100644 --- a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract_test.go +++ b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract_test.go @@ -65,82 +65,6 @@ func TestAccResourceMgmtRsOoBConsWithMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "priority", "unspecified"), ), }, - // Update with children - { - Config: testConfigMgmtRsOoBConsChildrenDependencyWithMgmtInstP, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "out_of_band_contract_name", "test_tn_vz_oob_br_cp_name"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "priority", "unspecified"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.1.value", "value_2"), - ), - }, - // Import testing with children - { - ResourceName: "aci_relation_to_consumed_out_of_band_contract.test", - ImportState: true, - ImportStateVerify: true, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "out_of_band_contract_name", "test_tn_vz_oob_br_cp_name"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "priority", "unspecified"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.1.value", "value_2"), - ), - }, - // Update with children removed from config - { - Config: testConfigMgmtRsOoBConsChildrenRemoveFromConfigDependencyWithMgmtInstP, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.#", "2"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.#", "2"), - ), - }, - // Update with children first child removed - { - Config: testConfigMgmtRsOoBConsChildrenRemoveOneDependencyWithMgmtInstP, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.#", "1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.#", "1"), - ), - }, - // Update with all children removed - { - Config: testConfigMgmtRsOoBConsChildrenRemoveAllDependencyWithMgmtInstP, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.#", "0"), - resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.#", "0"), - ), - }, }, }) } @@ -169,64 +93,3 @@ resource "aci_relation_to_consumed_out_of_band_contract" "test" { priority = "unspecified" } ` -const testConfigMgmtRsOoBConsChildrenDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` -resource "aci_relation_to_consumed_out_of_band_contract" "test" { - parent_dn = aci_external_management_network_instance_profile.test.id - out_of_band_contract_name = "test_tn_vz_oob_br_cp_name" - annotations = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigMgmtRsOoBConsChildrenRemoveFromConfigDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` -resource "aci_relation_to_consumed_out_of_band_contract" "test" { - parent_dn = aci_external_management_network_instance_profile.test.id - out_of_band_contract_name = "test_tn_vz_oob_br_cp_name" -} -` - -const testConfigMgmtRsOoBConsChildrenRemoveOneDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` -resource "aci_relation_to_consumed_out_of_band_contract" "test" { - parent_dn = aci_external_management_network_instance_profile.test.id - out_of_band_contract_name = "test_tn_vz_oob_br_cp_name" - annotations = [ - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigMgmtRsOoBConsChildrenRemoveAllDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` -resource "aci_relation_to_consumed_out_of_band_contract" "test" { - parent_dn = aci_external_management_network_instance_profile.test.id - out_of_band_contract_name = "test_tn_vz_oob_br_cp_name" - annotations = [] - tags = [] -} -` diff --git a/internal/provider/resource_aci_relation_to_fallback_route_group.go b/internal/provider/resource_aci_relation_to_fallback_route_group.go index 0809fa7d3..366bbb7f1 100644 --- a/internal/provider/resource_aci_relation_to_fallback_route_group.go +++ b/internal/provider/resource_aci_relation_to_fallback_route_group.go @@ -13,13 +13,11 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" @@ -42,46 +40,10 @@ type L3extRsOutToFBRGroupResource struct { // L3extRsOutToFBRGroupResourceModel describes the resource data model. type L3extRsOutToFBRGroupResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - TDn types.String `tfsdk:"target_dn"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` -} - -// TagAnnotationL3extRsOutToFBRGroupResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationL3extRsOutToFBRGroupResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationL3extRsOutToFBRGroupResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationL3extRsOutToFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationL3extRsOutToFBRGroupResourceModelAttributeTypes()) -} - -// TagTagL3extRsOutToFBRGroupResourceModel describes the resource data model for the children without relation ships. -type TagTagL3extRsOutToFBRGroupResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagL3extRsOutToFBRGroupResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagL3extRsOutToFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagL3extRsOutToFBRGroupResourceModelAttributeTypes()) + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + TDn types.String `tfsdk:"target_dn"` } type L3extRsOutToFBRGroupIdentifier struct { @@ -135,62 +97,6 @@ func (r *L3extRsOutToFBRGroupResource) Schema(ctx context.Context, req resource. }, MarkdownDescription: `The distinguished name of the VRF Fallback Route Group object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of resource: aci_relation_to_fallback_route_group") @@ -220,11 +126,6 @@ func (r *L3extRsOutToFBRGroupResource) Configure(ctx context.Context, req resour func (r *L3extRsOutToFBRGroupResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_relation_to_fallback_route_group") - // On create retrieve information on current state prior to making any changes in order to determine child delete operations - var stateData *L3extRsOutToFBRGroupResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) - setL3extRsOutToFBRGroupId(ctx, stateData) - getAndSetL3extRsOutToFBRGroupAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *L3extRsOutToFBRGroupResourceModel @@ -239,13 +140,7 @@ func (r *L3extRsOutToFBRGroupResource) Create(ctx context.Context, req resource. tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_relation_to_fallback_route_group with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsOutToFBRGroupResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagL3extRsOutToFBRGroupResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getL3extRsOutToFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getL3extRsOutToFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -292,11 +187,9 @@ func (r *L3extRsOutToFBRGroupResource) Read(ctx context.Context, req resource.Re func (r *L3extRsOutToFBRGroupResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_relation_to_fallback_route_group") var data *L3extRsOutToFBRGroupResourceModel - var stateData *L3extRsOutToFBRGroupResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -304,13 +197,7 @@ func (r *L3extRsOutToFBRGroupResource) Update(ctx context.Context, req resource. tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_relation_to_fallback_route_group with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsOutToFBRGroupResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagL3extRsOutToFBRGroupResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getL3extRsOutToFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getL3extRsOutToFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -364,7 +251,7 @@ func (r *L3extRsOutToFBRGroupResource) ImportState(ctx context.Context, req reso } func getAndSetL3extRsOutToFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *L3extRsOutToFBRGroupResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "l3extRsOutToFBRGroup,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -391,47 +278,6 @@ func getAndSetL3extRsOutToFBRGroupAttributes(ctx context.Context, diags *diag.Di if data.TDn.IsUnknown() { data.TDn = types.StringNull() } - TagAnnotationL3extRsOutToFBRGroup := TagAnnotationL3extRsOutToFBRGroupResourceModel{} - TagAnnotationL3extRsOutToFBRGroupList := make([]TagAnnotationL3extRsOutToFBRGroupResourceModel, 0) - TagTagL3extRsOutToFBRGroup := TagTagL3extRsOutToFBRGroupResourceModel{} - TagTagL3extRsOutToFBRGroupList := make([]TagTagL3extRsOutToFBRGroupResourceModel, 0) - _, ok := classReadInfo[0].(map[string]interface{})["children"] - if ok { - children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) - for _, child := range children { - for childClassName, childClassDetails := range child.(map[string]interface{}) { - childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) - if childClassName == "tagAnnotation" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagAnnotationL3extRsOutToFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationL3extRsOutToFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagAnnotationL3extRsOutToFBRGroupList = append(TagAnnotationL3extRsOutToFBRGroupList, TagAnnotationL3extRsOutToFBRGroup) - } - if childClassName == "tagTag" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagTagL3extRsOutToFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagL3extRsOutToFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagTagL3extRsOutToFBRGroupList = append(TagTagL3extRsOutToFBRGroupList, TagTagL3extRsOutToFBRGroup) - } - } - } - } - tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationL3extRsOutToFBRGroupList) - data.TagAnnotation = tagAnnotationSet - tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagL3extRsOutToFBRGroupList) - data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -474,102 +320,9 @@ func setL3extRsOutToFBRGroupId(ctx context.Context, data *L3extRsOutToFBRGroupRe data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getL3extRsOutToFBRGroupTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsOutToFBRGroupResourceModel, tagAnnotationL3extRsOutToFBRGroupPlan, tagAnnotationL3extRsOutToFBRGroupState []TagAnnotationL3extRsOutToFBRGroupResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { - tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotationL3extRsOutToFBRGroup := range tagAnnotationL3extRsOutToFBRGroupPlan { - if !tagAnnotationL3extRsOutToFBRGroup.Key.IsNull() && !tagAnnotationL3extRsOutToFBRGroup.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotationL3extRsOutToFBRGroup.Key.ValueString() - } - if !tagAnnotationL3extRsOutToFBRGroup.Value.IsNull() && !tagAnnotationL3extRsOutToFBRGroup.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotationL3extRsOutToFBRGroup.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) - tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotationL3extRsOutToFBRGroup.Key - tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) - } - for _, tagAnnotation := range tagAnnotationL3extRsOutToFBRGroupState { - delete := true - for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { - if tagAnnotationIdentifier.Key == tagAnnotation.Key { - delete = false - break - } - } - if delete { - tagAnnotationChildMapForDelete := NewAciObject() - tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" - tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) - } - } - } else { - data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) - } - - return childPayloads -} - -func getL3extRsOutToFBRGroupTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsOutToFBRGroupResourceModel, tagTagL3extRsOutToFBRGroupPlan, tagTagL3extRsOutToFBRGroupState []TagTagL3extRsOutToFBRGroupResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { - tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTagL3extRsOutToFBRGroup := range tagTagL3extRsOutToFBRGroupPlan { - if !tagTagL3extRsOutToFBRGroup.Key.IsNull() && !tagTagL3extRsOutToFBRGroup.Key.IsUnknown() { - childMap.Attributes["key"] = tagTagL3extRsOutToFBRGroup.Key.ValueString() - } - if !tagTagL3extRsOutToFBRGroup.Value.IsNull() && !tagTagL3extRsOutToFBRGroup.Value.IsUnknown() { - childMap.Attributes["value"] = tagTagL3extRsOutToFBRGroup.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) - tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTagL3extRsOutToFBRGroup.Key - tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) - } - for _, tagTag := range tagTagL3extRsOutToFBRGroupState { - delete := true - for _, tagTagIdentifier := range tagTagIdentifiers { - if tagTagIdentifier.Key == tagTag.Key { - delete = false - break - } - } - if delete { - tagTagChildMapForDelete := NewAciObject() - tagTagChildMapForDelete.Attributes["status"] = "deleted" - tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) - } - } - } else { - data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) - } - - return childPayloads -} - -func getL3extRsOutToFBRGroupCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *L3extRsOutToFBRGroupResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsOutToFBRGroupResourceModel, tagTagPlan, tagTagState []TagTagL3extRsOutToFBRGroupResourceModel) *container.Container { +func getL3extRsOutToFBRGroupCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *L3extRsOutToFBRGroupResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} - childPayloads := []map[string]interface{}{} - - TagAnnotationchildPayloads := getL3extRsOutToFBRGroupTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) - if TagAnnotationchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagAnnotationchildPayloads...) - - TagTagchildPayloads := getL3extRsOutToFBRGroupTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) - if TagTagchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagTagchildPayloads...) - - payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_relation_to_fallback_route_group_test.go b/internal/provider/resource_aci_relation_to_fallback_route_group_test.go index 6d59993bf..cdb9e31a1 100644 --- a/internal/provider/resource_aci_relation_to_fallback_route_group_test.go +++ b/internal/provider/resource_aci_relation_to_fallback_route_group_test.go @@ -61,80 +61,6 @@ func TestAccResourceL3extRsOutToFBRGroupWithL3extOut(t *testing.T) { resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotation", "orchestrator:terraform"), ), }, - // Update with children - { - Config: testConfigL3extRsOutToFBRGroupChildrenDependencyWithL3extOut, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "target_dn", "uni/tn-test_tenant/ctx-test_vrf/fbrg-fallback_route_group"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.1.value", "value_2"), - ), - }, - // Import testing with children - { - ResourceName: "aci_relation_to_fallback_route_group.test", - ImportState: true, - ImportStateVerify: true, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "target_dn", "uni/tn-test_tenant/ctx-test_vrf/fbrg-fallback_route_group"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.1.value", "value_2"), - ), - }, - // Update with children removed from config - { - Config: testConfigL3extRsOutToFBRGroupChildrenRemoveFromConfigDependencyWithL3extOut, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.#", "2"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.#", "2"), - ), - }, - // Update with children first child removed - { - Config: testConfigL3extRsOutToFBRGroupChildrenRemoveOneDependencyWithL3extOut, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.#", "1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.#", "1"), - ), - }, - // Update with all children removed - { - Config: testConfigL3extRsOutToFBRGroupChildrenRemoveAllDependencyWithL3extOut, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.#", "0"), - resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.#", "0"), - ), - }, }, }) } @@ -168,64 +94,3 @@ resource "aci_relation_to_fallback_route_group" "test" { annotation = "orchestrator:terraform" } ` -const testConfigL3extRsOutToFBRGroupChildrenDependencyWithL3extOut = testConfigfvFBRGroupMinDependencyWithFvCtx + testConfigL3extOutMinDependencyWithFvTenant + ` -resource "aci_relation_to_fallback_route_group" "test" { - parent_dn = aci_l3_outside.test.id - target_dn = aci_vrf_fallback_route_group.test.id - annotations = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigL3extRsOutToFBRGroupChildrenRemoveFromConfigDependencyWithL3extOut = testConfigfvFBRGroupMinDependencyWithFvCtx + testConfigL3extOutMinDependencyWithFvTenant + ` -resource "aci_relation_to_fallback_route_group" "test" { - parent_dn = aci_l3_outside.test.id - target_dn = aci_vrf_fallback_route_group.test.id -} -` - -const testConfigL3extRsOutToFBRGroupChildrenRemoveOneDependencyWithL3extOut = testConfigfvFBRGroupMinDependencyWithFvCtx + testConfigL3extOutMinDependencyWithFvTenant + ` -resource "aci_relation_to_fallback_route_group" "test" { - parent_dn = aci_l3_outside.test.id - target_dn = aci_vrf_fallback_route_group.test.id - annotations = [ - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigL3extRsOutToFBRGroupChildrenRemoveAllDependencyWithL3extOut = testConfigfvFBRGroupMinDependencyWithFvCtx + testConfigL3extOutMinDependencyWithFvTenant + ` -resource "aci_relation_to_fallback_route_group" "test" { - parent_dn = aci_l3_outside.test.id - target_dn = aci_vrf_fallback_route_group.test.id - annotations = [] - tags = [] -} -` diff --git a/internal/provider/resource_aci_vrf_fallback_route_group.go b/internal/provider/resource_aci_vrf_fallback_route_group.go index 38bc77029..f7e5737fd 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group.go @@ -42,26 +42,22 @@ type FvFBRGroupResource struct { // FvFBRGroupResourceModel describes the resource data model. type FvFBRGroupResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - FvFBRMember types.Set `tfsdk:"vrf_fallback_route_group_members"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + FvFBRMember types.Set `tfsdk:"vrf_fallback_route_group_members"` } // FvFBRMemberFvFBRGroupResourceModel describes the resource data model for the children without relation ships. type FvFBRMemberFvFBRGroupResourceModel struct { - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - RnhAddr types.String `tfsdk:"fallback_member"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + RnhAddr types.String `tfsdk:"fallback_member"` } func FvFBRMemberFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { @@ -71,8 +67,6 @@ func FvFBRMemberFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { "name": types.StringType, "name_alias": types.StringType, "fallback_member": types.StringType, - "annotations": types.SetType{ElemType: types.StringType}, - "tags": types.SetType{ElemType: types.StringType}, } } @@ -80,74 +74,6 @@ func FvFBRMemberFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, FvFBRMemberFvFBRGroupResourceModelAttributeTypes()) } -// TagAnnotationFvFBRMemberFvFBRGroupResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationFvFBRMemberFvFBRGroupResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationFvFBRMemberFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationFvFBRMemberFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvFBRMemberFvFBRGroupResourceModelAttributeTypes()) -} - -// TagTagFvFBRMemberFvFBRGroupResourceModel describes the resource data model for the children without relation ships. -type TagTagFvFBRMemberFvFBRGroupResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagFvFBRMemberFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagFvFBRMemberFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvFBRMemberFvFBRGroupResourceModelAttributeTypes()) -} - -// TagAnnotationFvFBRGroupResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationFvFBRGroupResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvFBRGroupResourceModelAttributeTypes()) -} - -// TagTagFvFBRGroupResourceModel describes the resource data model for the children without relation ships. -type TagTagFvFBRGroupResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvFBRGroupResourceModelAttributeTypes()) -} - type FvFBRGroupIdentifier struct { Name types.String } @@ -270,118 +196,6 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ }, MarkdownDescription: `The address of the VRF Fallback Route Group Member object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - }, - }, - }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, }, }, }, @@ -436,13 +250,7 @@ func (r *FvFBRGroupResource) Create(ctx context.Context, req resource.CreateRequ var fvFBRMemberPlan, fvFBRMemberState []FvFBRMemberFvFBRGroupResourceModel data.FvFBRMember.ElementsAs(ctx, &fvFBRMemberPlan, false) stateData.FvFBRMember.ElementsAs(ctx, &fvFBRMemberState, false) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvFBRGroupResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagFvFBRGroupResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getFvFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data, fvFBRMemberPlan, fvFBRMemberState, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getFvFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data, fvFBRMemberPlan, fvFBRMemberState) if resp.Diagnostics.HasError() { return @@ -504,13 +312,7 @@ func (r *FvFBRGroupResource) Update(ctx context.Context, req resource.UpdateRequ var fvFBRMemberPlan, fvFBRMemberState []FvFBRMemberFvFBRGroupResourceModel data.FvFBRMember.ElementsAs(ctx, &fvFBRMemberPlan, false) stateData.FvFBRMember.ElementsAs(ctx, &fvFBRMemberState, false) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvFBRGroupResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagFvFBRGroupResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getFvFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data, fvFBRMemberPlan, fvFBRMemberState, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getFvFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data, fvFBRMemberPlan, fvFBRMemberState) if resp.Diagnostics.HasError() { return @@ -564,7 +366,7 @@ func (r *FvFBRGroupResource) ImportState(ctx context.Context, req resource.Impor } func getAndSetFvFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *FvFBRGroupResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "fvFBRGroup,fvFBRMember,tagAnnotation,tagTag,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "fvFBRGroup,fvFBRMember"), "GET", nil) if diags.HasError() { return @@ -605,14 +407,6 @@ func getAndSetFvFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, } FvFBRMemberFvFBRGroup := FvFBRMemberFvFBRGroupResourceModel{} FvFBRMemberFvFBRGroupList := make([]FvFBRMemberFvFBRGroupResourceModel, 0) - TagAnnotationFvFBRMemberFvFBRGroup := TagAnnotationFvFBRMemberFvFBRGroupResourceModel{} - TagAnnotationFvFBRMemberFvFBRGroupList := make([]TagAnnotationFvFBRMemberFvFBRGroupResourceModel, 0) - TagTagFvFBRMemberFvFBRGroup := TagTagFvFBRMemberFvFBRGroupResourceModel{} - TagTagFvFBRMemberFvFBRGroupList := make([]TagTagFvFBRMemberFvFBRGroupResourceModel, 0) - TagAnnotationFvFBRGroup := TagAnnotationFvFBRGroupResourceModel{} - TagAnnotationFvFBRGroupList := make([]TagAnnotationFvFBRGroupResourceModel, 0) - TagTagFvFBRGroup := TagTagFvFBRGroupResourceModel{} - TagTagFvFBRGroupList := make([]TagTagFvFBRGroupResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) @@ -638,76 +432,13 @@ func getAndSetFvFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, } } - childrenOfFvFBRMemberFvFBRGroup, childrenOfFvFBRMemberFvFBRGroupExist := childClassDetails.(map[string]interface{})["children"] - if childrenOfFvFBRMemberFvFBRGroupExist { - for _, childFvFBRMemberFvFBRGroup := range childrenOfFvFBRMemberFvFBRGroup.([]interface{}) { - for childClassNameFvFBRMemberFvFBRGroup, childClassDetailsFvFBRMemberFvFBRGroup := range childFvFBRMemberFvFBRGroup.(map[string]interface{}) { - if childClassNameFvFBRMemberFvFBRGroup == "tagAnnotation" { - tagAnnotationchildAttributeValue := childClassDetailsFvFBRMemberFvFBRGroup.(map[string]interface{})["attributes"].(map[string]interface{}) - for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { - if childAttributeName == "key" { - TagAnnotationFvFBRMemberFvFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationFvFBRMemberFvFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - } - TagAnnotationFvFBRMemberFvFBRGroupList = append(TagAnnotationFvFBRMemberFvFBRGroupList, TagAnnotationFvFBRMemberFvFBRGroup) - } - if childClassNameFvFBRMemberFvFBRGroup == "tagTag" { - tagTagchildAttributeValue := childClassDetailsFvFBRMemberFvFBRGroup.(map[string]interface{})["attributes"].(map[string]interface{}) - for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { - if childAttributeName == "key" { - TagTagFvFBRMemberFvFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagFvFBRMemberFvFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - } - TagTagFvFBRMemberFvFBRGroupList = append(TagTagFvFBRMemberFvFBRGroupList, TagTagFvFBRMemberFvFBRGroup) - } - } - } - } - TagAnnotationSet, _ := types.SetValueFrom(ctx, TagAnnotationFvFBRMemberFvFBRGroupResourceModelElementType(), TagAnnotationFvFBRMemberFvFBRGroupList) - FvFBRMemberFvFBRGroup.TagAnnotation = TagAnnotationSet - TagTagSet, _ := types.SetValueFrom(ctx, TagTagFvFBRMemberFvFBRGroupResourceModelElementType(), TagTagFvFBRMemberFvFBRGroupList) - FvFBRMemberFvFBRGroup.TagTag = TagTagSet FvFBRMemberFvFBRGroupList = append(FvFBRMemberFvFBRGroupList, FvFBRMemberFvFBRGroup) } - if childClassName == "tagAnnotation" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagAnnotationFvFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationFvFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagAnnotationFvFBRGroupList = append(TagAnnotationFvFBRGroupList, TagAnnotationFvFBRGroup) - } - if childClassName == "tagTag" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagTagFvFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagFvFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagTagFvFBRGroupList = append(TagTagFvFBRGroupList, TagTagFvFBRGroup) - } } } } fvFBRMemberSet, _ := types.SetValueFrom(ctx, data.FvFBRMember.ElementType(ctx), FvFBRMemberFvFBRGroupList) data.FvFBRMember = fvFBRMemberSet - tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationFvFBRGroupList) - data.TagAnnotation = tagAnnotationSet - tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagFvFBRGroupList) - data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -751,14 +482,11 @@ func setFvFBRGroupId(ctx context.Context, data *FvFBRGroupResourceModel) { } func getFvFBRGroupFvFBRMemberChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, fvFBRMemberFvFBRGroupPlan, fvFBRMemberFvFBRGroupState []FvFBRMemberFvFBRGroupResourceModel) []map[string]interface{} { - childMap := NewAciObject() childPayloads := []map[string]interface{}{} - tagAnnotationFvFBRMemberFvFBRGroupChildMap := NewAciObject() - tagTagFvFBRMemberFvFBRGroupChildMap := NewAciObject() - FvFBRMemberFvFBRGroupChildren := make([]map[string]interface{}, 0) if !data.FvFBRMember.IsNull() && !data.FvFBRMember.IsUnknown() { fvFBRMemberIdentifiers := []FvFBRMemberIdentifier{} for _, fvFBRMemberFvFBRGroup := range fvFBRMemberFvFBRGroupPlan { + childMap := NewAciObject() if !fvFBRMemberFvFBRGroup.Annotation.IsNull() && !fvFBRMemberFvFBRGroup.Annotation.IsUnknown() { childMap.Attributes["annotation"] = fvFBRMemberFvFBRGroup.Annotation.ValueString() } else { @@ -776,49 +504,6 @@ func getFvFBRGroupFvFBRMemberChildPayloads(ctx context.Context, diags *diag.Diag if !fvFBRMemberFvFBRGroup.RnhAddr.IsNull() && !fvFBRMemberFvFBRGroup.RnhAddr.IsUnknown() { childMap.Attributes["rnhAddr"] = fvFBRMemberFvFBRGroup.RnhAddr.ValueString() } - var tagAnnotationFvFBRMemberFvFBRGroupPlan, tagAnnotationFvFBRMemberFvFBRGroupState []TagAnnotationFvFBRMemberFvFBRGroupResourceModel - fvFBRMemberFvFBRGroup.TagAnnotation.ElementsAs(ctx, &tagAnnotationFvFBRMemberFvFBRGroupPlan, false) - for _, fvFBRMembertagAnnotationState := range fvFBRMemberFvFBRGroupState { - fvFBRMembertagAnnotationState.TagAnnotation.ElementsAs(ctx, &tagAnnotationFvFBRMemberFvFBRGroupState, false) - if len(tagAnnotationFvFBRMemberFvFBRGroupPlan) == 0 && len(tagAnnotationFvFBRMemberFvFBRGroupState) == 1 { - tagAnnotationFvFBRMemberFvFBRGroupChildMap := NewAciObject() - tagAnnotationFvFBRMemberFvFBRGroupChildMap.Attributes["status"] = "deleted" - FvFBRMemberFvFBRGroupChildren = append(FvFBRMemberFvFBRGroupChildren, map[string]interface{}{"tagAnnotation": tagAnnotationFvFBRMemberFvFBRGroupChildMap}) - } - } - if !fvFBRMemberFvFBRGroup.TagAnnotation.IsNull() && !fvFBRMemberFvFBRGroup.TagAnnotation.IsUnknown() { - for _, tagAnnotationFvFBRMemberFvFBRGroup := range tagAnnotationFvFBRMemberFvFBRGroupPlan { - if !tagAnnotationFvFBRMemberFvFBRGroup.Key.IsNull() && !tagAnnotationFvFBRMemberFvFBRGroup.Key.IsUnknown() { - tagAnnotationFvFBRMemberFvFBRGroupChildMap.Attributes["key"] = tagAnnotationFvFBRMemberFvFBRGroup.Key.ValueString() - } - if !tagAnnotationFvFBRMemberFvFBRGroup.Value.IsNull() && !tagAnnotationFvFBRMemberFvFBRGroup.Value.IsUnknown() { - tagAnnotationFvFBRMemberFvFBRGroupChildMap.Attributes["value"] = tagAnnotationFvFBRMemberFvFBRGroup.Value.ValueString() - } - FvFBRMemberFvFBRGroupChildren = append(FvFBRMemberFvFBRGroupChildren, map[string]interface{}{"tagAnnotation": tagAnnotationFvFBRMemberFvFBRGroupChildMap}) - } - } - var tagTagFvFBRMemberFvFBRGroupPlan, tagTagFvFBRMemberFvFBRGroupState []TagTagFvFBRMemberFvFBRGroupResourceModel - fvFBRMemberFvFBRGroup.TagTag.ElementsAs(ctx, &tagTagFvFBRMemberFvFBRGroupPlan, false) - for _, fvFBRMembertagTagState := range fvFBRMemberFvFBRGroupState { - fvFBRMembertagTagState.TagTag.ElementsAs(ctx, &tagTagFvFBRMemberFvFBRGroupState, false) - if len(tagTagFvFBRMemberFvFBRGroupPlan) == 0 && len(tagTagFvFBRMemberFvFBRGroupState) == 1 { - tagTagFvFBRMemberFvFBRGroupChildMap := NewAciObject() - tagTagFvFBRMemberFvFBRGroupChildMap.Attributes["status"] = "deleted" - FvFBRMemberFvFBRGroupChildren = append(FvFBRMemberFvFBRGroupChildren, map[string]interface{}{"tagTag": tagTagFvFBRMemberFvFBRGroupChildMap}) - } - } - if !fvFBRMemberFvFBRGroup.TagTag.IsNull() && !fvFBRMemberFvFBRGroup.TagTag.IsUnknown() { - for _, tagTagFvFBRMemberFvFBRGroup := range tagTagFvFBRMemberFvFBRGroupPlan { - if !tagTagFvFBRMemberFvFBRGroup.Key.IsNull() && !tagTagFvFBRMemberFvFBRGroup.Key.IsUnknown() { - tagTagFvFBRMemberFvFBRGroupChildMap.Attributes["key"] = tagTagFvFBRMemberFvFBRGroup.Key.ValueString() - } - if !tagTagFvFBRMemberFvFBRGroup.Value.IsNull() && !tagTagFvFBRMemberFvFBRGroup.Value.IsUnknown() { - tagTagFvFBRMemberFvFBRGroupChildMap.Attributes["value"] = tagTagFvFBRMemberFvFBRGroup.Value.ValueString() - } - FvFBRMemberFvFBRGroupChildren = append(FvFBRMemberFvFBRGroupChildren, map[string]interface{}{"tagTag": tagTagFvFBRMemberFvFBRGroupChildMap}) - } - } - childMap.Children = FvFBRMemberFvFBRGroupChildren childPayloads = append(childPayloads, map[string]interface{}{"fvFBRMember": childMap}) fvFBRMemberIdentifier := FvFBRMemberIdentifier{} fvFBRMemberIdentifier.RnhAddr = fvFBRMemberFvFBRGroup.RnhAddr @@ -846,85 +531,7 @@ func getFvFBRGroupFvFBRMemberChildPayloads(ctx context.Context, diags *diag.Diag return childPayloads } -func getFvFBRGroupTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, tagAnnotationFvFBRGroupPlan, tagAnnotationFvFBRGroupState []TagAnnotationFvFBRGroupResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { - tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotationFvFBRGroup := range tagAnnotationFvFBRGroupPlan { - if !tagAnnotationFvFBRGroup.Key.IsNull() && !tagAnnotationFvFBRGroup.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotationFvFBRGroup.Key.ValueString() - } - if !tagAnnotationFvFBRGroup.Value.IsNull() && !tagAnnotationFvFBRGroup.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotationFvFBRGroup.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) - tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotationFvFBRGroup.Key - tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) - } - for _, tagAnnotation := range tagAnnotationFvFBRGroupState { - delete := true - for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { - if tagAnnotationIdentifier.Key == tagAnnotation.Key { - delete = false - break - } - } - if delete { - tagAnnotationChildMapForDelete := NewAciObject() - tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" - tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) - } - } - } else { - data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) - } - - return childPayloads -} - -func getFvFBRGroupTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, tagTagFvFBRGroupPlan, tagTagFvFBRGroupState []TagTagFvFBRGroupResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { - tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTagFvFBRGroup := range tagTagFvFBRGroupPlan { - if !tagTagFvFBRGroup.Key.IsNull() && !tagTagFvFBRGroup.Key.IsUnknown() { - childMap.Attributes["key"] = tagTagFvFBRGroup.Key.ValueString() - } - if !tagTagFvFBRGroup.Value.IsNull() && !tagTagFvFBRGroup.Value.IsUnknown() { - childMap.Attributes["value"] = tagTagFvFBRGroup.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) - tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTagFvFBRGroup.Key - tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) - } - for _, tagTag := range tagTagFvFBRGroupState { - delete := true - for _, tagTagIdentifier := range tagTagIdentifiers { - if tagTagIdentifier.Key == tagTag.Key { - delete = false - break - } - } - if delete { - tagTagChildMapForDelete := NewAciObject() - tagTagChildMapForDelete.Attributes["status"] = "deleted" - tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) - } - } - } else { - data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) - } - - return childPayloads -} - -func getFvFBRGroupCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, fvFBRMemberPlan, fvFBRMemberState []FvFBRMemberFvFBRGroupResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvFBRGroupResourceModel, tagTagPlan, tagTagState []TagTagFvFBRGroupResourceModel) *container.Container { +func getFvFBRGroupCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, fvFBRMemberPlan, fvFBRMemberState []FvFBRMemberFvFBRGroupResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} childPayloads := []map[string]interface{}{} @@ -935,18 +542,6 @@ func getFvFBRGroupCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics } childPayloads = append(childPayloads, FvFBRMemberchildPayloads...) - TagAnnotationchildPayloads := getFvFBRGroupTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) - if TagAnnotationchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagAnnotationchildPayloads...) - - TagTagchildPayloads := getFvFBRGroupTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) - if TagTagchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagTagchildPayloads...) - payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() diff --git a/internal/provider/resource_aci_vrf_fallback_route_group_member.go b/internal/provider/resource_aci_vrf_fallback_route_group_member.go index 31cb4b7e0..ab471d4c3 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group_member.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group_member.go @@ -13,13 +13,11 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" @@ -42,49 +40,13 @@ type FvFBRMemberResource struct { // FvFBRMemberResourceModel describes the resource data model. type FvFBRMemberResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - RnhAddr types.String `tfsdk:"fallback_member"` - TagAnnotation types.Set `tfsdk:"annotations"` - TagTag types.Set `tfsdk:"tags"` -} - -// TagAnnotationFvFBRMemberResourceModel describes the resource data model for the children without relation ships. -type TagAnnotationFvFBRMemberResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagAnnotationFvFBRMemberResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagAnnotationFvFBRMemberResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvFBRMemberResourceModelAttributeTypes()) -} - -// TagTagFvFBRMemberResourceModel describes the resource data model for the children without relation ships. -type TagTagFvFBRMemberResourceModel struct { - Key types.String `tfsdk:"key"` - Value types.String `tfsdk:"value"` -} - -func TagTagFvFBRMemberResourceModelAttributeTypes() map[string]attr.Type { - return map[string]attr.Type{ - "key": types.StringType, - "value": types.StringType, - } -} - -func TagTagFvFBRMemberResourceModelElementType() attr.TypeWithAttributeTypes { - return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvFBRMemberResourceModelAttributeTypes()) + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + RnhAddr types.String `tfsdk:"fallback_member"` } type FvFBRMemberIdentifier struct { @@ -165,62 +127,6 @@ func (r *FvFBRMemberResource) Schema(ctx context.Context, req resource.SchemaReq }, MarkdownDescription: `The address of the VRF Fallback Route Group Member object.`, }, - "annotations": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, - "tags": schema.SetNestedAttribute{ - MarkdownDescription: ``, - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.Set{ - setplanmodifier.UseStateForUnknown(), - }, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "key": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The key used to uniquely identify this configuration object.`, - }, - "value": schema.StringAttribute{ - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), - }, - MarkdownDescription: `The value of the property.`, - }, - }, - }, - }, }, } tflog.Debug(ctx, "End schema of resource: aci_vrf_fallback_route_group_member") @@ -250,11 +156,6 @@ func (r *FvFBRMemberResource) Configure(ctx context.Context, req resource.Config func (r *FvFBRMemberResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_vrf_fallback_route_group_member") - // On create retrieve information on current state prior to making any changes in order to determine child delete operations - var stateData *FvFBRMemberResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) - setFvFBRMemberId(ctx, stateData) - getAndSetFvFBRMemberAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *FvFBRMemberResourceModel @@ -269,13 +170,7 @@ func (r *FvFBRMemberResource) Create(ctx context.Context, req resource.CreateReq tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_vrf_fallback_route_group_member with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvFBRMemberResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagFvFBRMemberResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getFvFBRMemberCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getFvFBRMemberCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -322,11 +217,9 @@ func (r *FvFBRMemberResource) Read(ctx context.Context, req resource.ReadRequest func (r *FvFBRMemberResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_vrf_fallback_route_group_member") var data *FvFBRMemberResourceModel - var stateData *FvFBRMemberResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -334,13 +227,7 @@ func (r *FvFBRMemberResource) Update(ctx context.Context, req resource.UpdateReq tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_vrf_fallback_route_group_member with id '%s'", data.Id.ValueString())) - var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvFBRMemberResourceModel - data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) - stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) - var tagTagPlan, tagTagState []TagTagFvFBRMemberResourceModel - data.TagTag.ElementsAs(ctx, &tagTagPlan, false) - stateData.TagTag.ElementsAs(ctx, &tagTagState, false) - jsonPayload := getFvFBRMemberCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) + jsonPayload := getFvFBRMemberCreateJsonPayload(ctx, &resp.Diagnostics, data) if resp.Diagnostics.HasError() { return @@ -394,7 +281,7 @@ func (r *FvFBRMemberResource) ImportState(ctx context.Context, req resource.Impo } func getAndSetFvFBRMemberAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *FvFBRMemberResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "fvFBRMember,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) if diags.HasError() { return @@ -439,47 +326,6 @@ func getAndSetFvFBRMemberAttributes(ctx context.Context, diags *diag.Diagnostics if data.RnhAddr.IsUnknown() { data.RnhAddr = types.StringNull() } - TagAnnotationFvFBRMember := TagAnnotationFvFBRMemberResourceModel{} - TagAnnotationFvFBRMemberList := make([]TagAnnotationFvFBRMemberResourceModel, 0) - TagTagFvFBRMember := TagTagFvFBRMemberResourceModel{} - TagTagFvFBRMemberList := make([]TagTagFvFBRMemberResourceModel, 0) - _, ok := classReadInfo[0].(map[string]interface{})["children"] - if ok { - children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) - for _, child := range children { - for childClassName, childClassDetails := range child.(map[string]interface{}) { - childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) - if childClassName == "tagAnnotation" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagAnnotationFvFBRMember.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagAnnotationFvFBRMember.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagAnnotationFvFBRMemberList = append(TagAnnotationFvFBRMemberList, TagAnnotationFvFBRMember) - } - if childClassName == "tagTag" { - for childAttributeName, childAttributeValue := range childAttributes { - if childAttributeName == "key" { - TagTagFvFBRMember.Key = basetypes.NewStringValue(childAttributeValue.(string)) - } - if childAttributeName == "value" { - TagTagFvFBRMember.Value = basetypes.NewStringValue(childAttributeValue.(string)) - } - - } - TagTagFvFBRMemberList = append(TagTagFvFBRMemberList, TagTagFvFBRMember) - } - } - } - } - tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationFvFBRMemberList) - data.TagAnnotation = tagAnnotationSet - tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagFvFBRMemberList) - data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -522,102 +368,9 @@ func setFvFBRMemberId(ctx context.Context, data *FvFBRMemberResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getFvFBRMemberTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRMemberResourceModel, tagAnnotationFvFBRMemberPlan, tagAnnotationFvFBRMemberState []TagAnnotationFvFBRMemberResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { - tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotationFvFBRMember := range tagAnnotationFvFBRMemberPlan { - if !tagAnnotationFvFBRMember.Key.IsNull() && !tagAnnotationFvFBRMember.Key.IsUnknown() { - childMap.Attributes["key"] = tagAnnotationFvFBRMember.Key.ValueString() - } - if !tagAnnotationFvFBRMember.Value.IsNull() && !tagAnnotationFvFBRMember.Value.IsUnknown() { - childMap.Attributes["value"] = tagAnnotationFvFBRMember.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) - tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotationFvFBRMember.Key - tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) - } - for _, tagAnnotation := range tagAnnotationFvFBRMemberState { - delete := true - for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { - if tagAnnotationIdentifier.Key == tagAnnotation.Key { - delete = false - break - } - } - if delete { - tagAnnotationChildMapForDelete := NewAciObject() - tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" - tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) - } - } - } else { - data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) - } - - return childPayloads -} - -func getFvFBRMemberTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRMemberResourceModel, tagTagFvFBRMemberPlan, tagTagFvFBRMemberState []TagTagFvFBRMemberResourceModel) []map[string]interface{} { - childMap := NewAciObject() - childPayloads := []map[string]interface{}{} - if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { - tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTagFvFBRMember := range tagTagFvFBRMemberPlan { - if !tagTagFvFBRMember.Key.IsNull() && !tagTagFvFBRMember.Key.IsUnknown() { - childMap.Attributes["key"] = tagTagFvFBRMember.Key.ValueString() - } - if !tagTagFvFBRMember.Value.IsNull() && !tagTagFvFBRMember.Value.IsUnknown() { - childMap.Attributes["value"] = tagTagFvFBRMember.Value.ValueString() - } - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) - tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTagFvFBRMember.Key - tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) - } - for _, tagTag := range tagTagFvFBRMemberState { - delete := true - for _, tagTagIdentifier := range tagTagIdentifiers { - if tagTagIdentifier.Key == tagTag.Key { - delete = false - break - } - } - if delete { - tagTagChildMapForDelete := NewAciObject() - tagTagChildMapForDelete.Attributes["status"] = "deleted" - tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) - } - } - } else { - data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) - } - - return childPayloads -} - -func getFvFBRMemberCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvFBRMemberResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvFBRMemberResourceModel, tagTagPlan, tagTagState []TagTagFvFBRMemberResourceModel) *container.Container { +func getFvFBRMemberCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvFBRMemberResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} - childPayloads := []map[string]interface{}{} - - TagAnnotationchildPayloads := getFvFBRMemberTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) - if TagAnnotationchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagAnnotationchildPayloads...) - - TagTagchildPayloads := getFvFBRMemberTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) - if TagTagchildPayloads == nil { - return nil - } - childPayloads = append(childPayloads, TagTagchildPayloads...) - - payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_vrf_fallback_route_group_member_test.go b/internal/provider/resource_aci_vrf_fallback_route_group_member_test.go index 109e716b9..be80ea36d 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group_member_test.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group_member_test.go @@ -73,86 +73,6 @@ func TestAccResourceFvFBRMemberWithFvFBRGroup(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "name_alias", ""), ), }, - // Update with children - { - Config: testConfigFvFBRMemberChildrenDependencyWithFvFBRGroup, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "fallback_member", "2.2.2.3"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "description", ""), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "name", ""), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.1.value", "value_2"), - ), - }, - // Import testing with children - { - ResourceName: "aci_vrf_fallback_route_group_member.test", - ImportState: true, - ImportStateVerify: true, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "fallback_member", "2.2.2.3"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotation", "orchestrator:terraform"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "description", ""), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "name", ""), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.1.value", "value_2"), - ), - }, - // Update with children removed from config - { - Config: testConfigFvFBRMemberChildrenRemoveFromConfigDependencyWithFvFBRGroup, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.#", "2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.#", "2"), - ), - }, - // Update with children first child removed - { - Config: testConfigFvFBRMemberChildrenRemoveOneDependencyWithFvFBRGroup, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.#", "1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.#", "1"), - ), - }, - // Update with all children removed - { - Config: testConfigFvFBRMemberChildrenRemoveAllDependencyWithFvFBRGroup, - ExpectNonEmptyPlan: false, - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.#", "0"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.#", "0"), - ), - }, }, }) } @@ -185,64 +105,3 @@ resource "aci_vrf_fallback_route_group_member" "test" { name_alias = "" } ` -const testConfigFvFBRMemberChildrenDependencyWithFvFBRGroup = testConfigFvFBRGroupMinDependencyWithFvCtx + ` -resource "aci_vrf_fallback_route_group_member" "test" { - parent_dn = aci_vrf_fallback_route_group.test.id - fallback_member = "2.2.2.3" - annotations = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigFvFBRMemberChildrenRemoveFromConfigDependencyWithFvFBRGroup = testConfigFvFBRGroupMinDependencyWithFvCtx + ` -resource "aci_vrf_fallback_route_group_member" "test" { - parent_dn = aci_vrf_fallback_route_group.test.id - fallback_member = "2.2.2.3" -} -` - -const testConfigFvFBRMemberChildrenRemoveOneDependencyWithFvFBRGroup = testConfigFvFBRGroupMinDependencyWithFvCtx + ` -resource "aci_vrf_fallback_route_group_member" "test" { - parent_dn = aci_vrf_fallback_route_group.test.id - fallback_member = "2.2.2.3" - annotations = [ - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_1" - value = "value_2" - }, - ] -} -` - -const testConfigFvFBRMemberChildrenRemoveAllDependencyWithFvFBRGroup = testConfigFvFBRGroupMinDependencyWithFvCtx + ` -resource "aci_vrf_fallback_route_group_member" "test" { - parent_dn = aci_vrf_fallback_route_group.test.id - fallback_member = "2.2.2.3" - annotations = [] - tags = [] -} -` diff --git a/internal/provider/resource_aci_vrf_fallback_route_group_test.go b/internal/provider/resource_aci_vrf_fallback_route_group_test.go index 9978f34be..466f47e45 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group_test.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group_test.go @@ -78,14 +78,6 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotation", "orchestrator:terraform"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "description", ""), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.1.value", "value_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.description", "description_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.fallback_member", "2.2.2.2"), @@ -108,14 +100,6 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotation", "orchestrator:terraform"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "description", ""), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "name_alias", ""), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.1.value", "value_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.description", "description_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.fallback_member", "2.2.2.2"), @@ -133,16 +117,6 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { Config: testConfigFvFBRGroupChildrenRemoveFromConfigDependencyWithFvCtx, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.#", "2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.key", "key_0"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.value", "value_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.1.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.1.value", "value_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.#", "2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.description", "description_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.fallback_member", "2.2.2.2"), @@ -161,12 +135,6 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { Config: testConfigFvFBRGroupChildrenRemoveOneDependencyWithFvCtx, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.#", "1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.key", "key_1"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.value", "value_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.#", "1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.annotation", "annotation_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.description", "description_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.fallback_member", "2.2.2.3"), @@ -180,8 +148,6 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { Config: testConfigFvFBRGroupChildrenRemoveAllDependencyWithFvCtx, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.#", "0"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.#", "0"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.#", "0"), ), }, @@ -219,26 +185,6 @@ const testConfigFvFBRGroupChildrenDependencyWithFvCtx = testConfigFvCtxMinDepend resource "aci_vrf_fallback_route_group" "test" { parent_dn = aci_vrf.test.id name = "fallback_route_group" - annotations = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_0" - value = "value_1" - }, - { - key = "key_1" - value = "value_2" - }, - ] vrf_fallback_route_group_members = [ { annotation = "annotation_1" @@ -269,18 +215,6 @@ const testConfigFvFBRGroupChildrenRemoveOneDependencyWithFvCtx = testConfigFvCtx resource "aci_vrf_fallback_route_group" "test" { parent_dn = aci_vrf.test.id name = "fallback_route_group" - annotations = [ - { - key = "key_1" - value = "value_2" - }, - ] - tags = [ - { - key = "key_1" - value = "value_2" - }, - ] vrf_fallback_route_group_members = [ { annotation = "annotation_2" @@ -297,8 +231,6 @@ const testConfigFvFBRGroupChildrenRemoveAllDependencyWithFvCtx = testConfigFvCtx resource "aci_vrf_fallback_route_group" "test" { parent_dn = aci_vrf.test.id name = "fallback_route_group" - annotations = [] - tags = [] vrf_fallback_route_group_members = [] } ` From 15c736aaa8e7ff87353f52ff2dcc1a7822852864 Mon Sep 17 00:00:00 2001 From: Shreyas Date: Tue, 7 May 2024 21:43:11 -0400 Subject: [PATCH 10/20] [ignore] Changed element type of set attributes which is part of a an object for nested children --- docs/data-sources/endpoint_tag_ip.md | 8 + docs/data-sources/endpoint_tag_mac.md | 8 + ...nal_management_network_instance_profile.md | 8 + .../external_management_network_subnet.md | 8 + docs/data-sources/l3out_consumer_label.md | 8 + .../data-sources/l3out_redistribute_policy.md | 8 + docs/data-sources/out_of_band_contract.md | 8 + docs/data-sources/pim_route_map_entry.md | 8 + docs/data-sources/pim_route_map_policy.md | 8 + ...lation_to_consumed_out_of_band_contract.md | 8 + .../relation_to_fallback_route_group.md | 8 + docs/data-sources/vrf_fallback_route_group.md | 8 + .../vrf_fallback_route_group_member.md | 8 + docs/resources/endpoint_tag_ip.md | 26 + docs/resources/endpoint_tag_mac.md | 26 + ...nal_management_network_instance_profile.md | 26 + .../external_management_network_subnet.md | 26 + docs/resources/l3out_consumer_label.md | 26 + docs/resources/l3out_redistribute_policy.md | 26 + docs/resources/out_of_band_contract.md | 26 + docs/resources/pim_route_map_entry.md | 26 + docs/resources/pim_route_map_policy.md | 26 + ...lation_to_consumed_out_of_band_contract.md | 26 + .../relation_to_fallback_route_group.md | 26 + docs/resources/vrf_fallback_route_group.md | 26 + .../vrf_fallback_route_group_member.md | 26 + .../resource-all-attributes.tf | 12 + .../resource-all-attributes.tf | 12 + .../resource-all-attributes.tf | 12 + .../resource-all-attributes.tf | 12 + .../resource-all-attributes.tf | 12 + .../resource-all-attributes.tf | 12 + .../resource-all-attributes.tf | 12 + .../resource-all-attributes.tf | 12 + .../resource-all-attributes.tf | 12 + .../resource-all-attributes.tf | 12 + .../resource-all-attributes.tf | 12 + .../resource-all-attributes.tf | 12 + .../resource-all-attributes.tf | 12 + gen/definitions/classes.yaml | 12 +- gen/generator.go | 2 +- gen/templates/resource.go.tmpl | 57 +- gen/testvars/fvEpIpTag.yaml | 15 + gen/testvars/fvEpMacTag.yaml | 15 + gen/testvars/fvFBRGroup.yaml | 14 + gen/testvars/fvFBRMember.yaml | 15 + gen/testvars/l3extConsLbl.yaml | 15 + gen/testvars/l3extRsOutToFBRGroup.yaml | 15 + gen/testvars/l3extRsRedistributePol.yaml | 15 + gen/testvars/mgmtInstP.yaml | 14 + gen/testvars/mgmtRsOoBCons.yaml | 15 + gen/testvars/mgmtSubnet.yaml | 15 + gen/testvars/pimRouteMapEntry.yaml | 15 + gen/testvars/pimRouteMapPol.yaml | 15 + gen/testvars/vzOOBBrCP.yaml | 15 + .../data_source_aci_endpoint_tag_ip.go | 32 + .../data_source_aci_endpoint_tag_mac.go | 32 + ...nal_management_network_instance_profile.go | 32 + ..._aci_external_management_network_subnet.go | 32 + .../data_source_aci_l3out_consumer_label.go | 32 + ...ta_source_aci_l3out_redistribute_policy.go | 32 + .../data_source_aci_out_of_band_contract.go | 32 + .../data_source_aci_pim_route_map_entry.go | 32 + .../data_source_aci_pim_route_map_policy.go | 32 + ...lation_to_consumed_out_of_band_contract.go | 32 + ...ce_aci_relation_to_fallback_route_group.go | 32 + ...ata_source_aci_vrf_fallback_route_group.go | 32 + ...rce_aci_vrf_fallback_route_group_member.go | 32 + .../resource_aci_communication_policy.go | 594 ++++++++++++++++-- .../provider/resource_aci_endpoint_tag_ip.go | 271 +++++++- .../resource_aci_endpoint_tag_ip_test.go | 147 +++++ .../provider/resource_aci_endpoint_tag_mac.go | 271 +++++++- .../resource_aci_endpoint_tag_mac_test.go | 147 +++++ ...nal_management_network_instance_profile.go | 443 ++++++++++++- ...anagement_network_instance_profile_test.go | 62 ++ ..._aci_external_management_network_subnet.go | 269 +++++++- ...external_management_network_subnet_test.go | 141 +++++ .../resource_aci_l3out_consumer_label.go | 275 +++++++- .../resource_aci_l3out_consumer_label_test.go | 147 +++++ .../resource_aci_l3out_redistribute_policy.go | 255 +++++++- ...urce_aci_l3out_redistribute_policy_test.go | 141 +++++ .../resource_aci_out_of_band_contract.go | 277 +++++++- .../resource_aci_out_of_band_contract_test.go | 145 +++++ .../resource_aci_pim_route_map_entry.go | 277 +++++++- .../resource_aci_pim_route_map_entry_test.go | 149 +++++ .../resource_aci_pim_route_map_policy.go | 271 +++++++- .../resource_aci_pim_route_map_policy_test.go | 143 +++++ ...lation_to_consumed_out_of_band_contract.go | 255 +++++++- ...n_to_consumed_out_of_band_contract_test.go | 137 ++++ ...ce_aci_relation_to_fallback_route_group.go | 263 +++++++- ...i_relation_to_fallback_route_group_test.go | 135 ++++ .../resource_aci_vrf_fallback_route_group.go | 467 +++++++++++++- ...rce_aci_vrf_fallback_route_group_member.go | 269 +++++++- ...ci_vrf_fallback_route_group_member_test.go | 141 +++++ ...ource_aci_vrf_fallback_route_group_test.go | 68 ++ 95 files changed, 7229 insertions(+), 209 deletions(-) diff --git a/docs/data-sources/endpoint_tag_ip.md b/docs/data-sources/endpoint_tag_ip.md index 41eb358bd..92bd7d66a 100644 --- a/docs/data-sources/endpoint_tag_ip.md +++ b/docs/data-sources/endpoint_tag_ip.md @@ -54,3 +54,11 @@ data "aci_endpoint_tag_ip" "example_tenant" { * `id_attribute` (id) - (string) The identifier of the Endpoint Tag Ip object. * `name` (name) - (string) The name of the Endpoint Tag Ip object. * `name_alias` (nameAlias) - (string) The name alias of the Endpoint Tag Ip object. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/endpoint_tag_mac.md b/docs/data-sources/endpoint_tag_mac.md index 14239b98a..65de071a0 100644 --- a/docs/data-sources/endpoint_tag_mac.md +++ b/docs/data-sources/endpoint_tag_mac.md @@ -54,3 +54,11 @@ data "aci_endpoint_tag_mac" "example_tenant" { * `id_attribute` (id) - (string) The identifier of the Endpoint Tag Mac object. * `name` (name) - (string) The name of the Endpoint Tag Mac object. * `name_alias` (nameAlias) - (string) The name alias of the Endpoint Tag Mac object. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/external_management_network_instance_profile.md b/docs/data-sources/external_management_network_instance_profile.md index a2ca8fb39..0b13ab7d4 100644 --- a/docs/data-sources/external_management_network_instance_profile.md +++ b/docs/data-sources/external_management_network_instance_profile.md @@ -54,3 +54,11 @@ data "aci_external_management_network_instance_profile" "example" { * `annotation` (annotation) - (string) The annotation of the Relation To Consumed Out Of Band Contract object. * `priority` (prio) - (string) The Quality of service (QoS) priority class ID. QoS refers to the capability of a network to provide better service to selected network traffic over various technologies. The primary goal of QoS is to provide priority including dedicated bandwidth, controlled jitter and latency (required by some real-time and interactive traffic), and improved loss characteristics. You can configure the bandwidth of each QoS level using QoS profiles. * `out_of_band_contract_name` (tnVzOOBBrCPName) - (string) The name of the Out Of Band Contract object. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/external_management_network_subnet.md b/docs/data-sources/external_management_network_subnet.md index 761df2bfd..663394bb0 100644 --- a/docs/data-sources/external_management_network_subnet.md +++ b/docs/data-sources/external_management_network_subnet.md @@ -52,3 +52,11 @@ data "aci_external_management_network_subnet" "example_external_management_netwo * `description` (descr) - (string) The description of the External Management Network Subnet object. * `name` (name) - (string) The name of the External Management Network Subnet object. * `name_alias` (nameAlias) - (string) The name alias of the External Management Network Subnet object. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/l3out_consumer_label.md b/docs/data-sources/l3out_consumer_label.md index 105b1e6cd..d9031ba6e 100644 --- a/docs/data-sources/l3out_consumer_label.md +++ b/docs/data-sources/l3out_consumer_label.md @@ -57,3 +57,11 @@ data "aci_l3out_consumer_label" "example_l3_outside" { * `owner_key` (ownerKey) - (string) The key for enabling clients to own their data for entity correlation. * `owner_tag` (ownerTag) - (string) A tag for enabling clients to add their own data. For example, to indicate who created this object. * `tag` (tag) - (string) Specifies the color of a policy label. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/l3out_redistribute_policy.md b/docs/data-sources/l3out_redistribute_policy.md index 0d1e91bb4..521d2d3ca 100644 --- a/docs/data-sources/l3out_redistribute_policy.md +++ b/docs/data-sources/l3out_redistribute_policy.md @@ -52,3 +52,11 @@ data "aci_l3out_redistribute_policy" "example_l3_outside" { * `id` - (string) The distinguished name (DN) of the L3out Redistribute Policy object. * `annotation` (annotation) - (string) The annotation of the L3out Redistribute Policy object. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/out_of_band_contract.md b/docs/data-sources/out_of_band_contract.md index 50b2218bf..5265a5b02 100644 --- a/docs/data-sources/out_of_band_contract.md +++ b/docs/data-sources/out_of_band_contract.md @@ -54,3 +54,11 @@ data "aci_out_of_band_contract" "example" { * `priority` (prio) - (string) The priority of the Out Of Band Contract object. * `scope` (scope) - (string) Represents the scope of this contract. If the scope is set as application-profile, the epg can only communicate with epgs in the same application-profile. * `target_dscp` (targetDscp) - (string) The target DSCP value of the Out Of Band Contract object. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/pim_route_map_entry.md b/docs/data-sources/pim_route_map_entry.md index fe80bd386..b999b7b7a 100644 --- a/docs/data-sources/pim_route_map_entry.md +++ b/docs/data-sources/pim_route_map_entry.md @@ -56,3 +56,11 @@ data "aci_pim_route_map_entry" "example_pim_route_map_policy" { * `name_alias` (nameAlias) - (string) The name alias of the Pim Route Map Entry object. * `rendezvous_point_ip` (rp) - (string) The rendezvous point ip of the Pim Route Map Entry object. * `source_ip` (src) - (string) The source ip of the Pim Route Map Entry object. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/pim_route_map_policy.md b/docs/data-sources/pim_route_map_policy.md index b99ae6323..a082c1702 100644 --- a/docs/data-sources/pim_route_map_policy.md +++ b/docs/data-sources/pim_route_map_policy.md @@ -53,3 +53,11 @@ data "aci_pim_route_map_policy" "example_tenant" { * `name_alias` (nameAlias) - (string) The name alias of the Pim Route Map Policy object. * `owner_key` (ownerKey) - (string) The key for enabling clients to own their data for entity correlation. * `owner_tag` (ownerTag) - (string) A tag for enabling clients to add their own data. For example, to indicate who created this object. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/relation_to_consumed_out_of_band_contract.md b/docs/data-sources/relation_to_consumed_out_of_band_contract.md index a60b57ef8..9e08ccb8e 100644 --- a/docs/data-sources/relation_to_consumed_out_of_band_contract.md +++ b/docs/data-sources/relation_to_consumed_out_of_band_contract.md @@ -50,3 +50,11 @@ data "aci_relation_to_consumed_out_of_band_contract" "example_external_managemen * `id` - (string) The distinguished name (DN) of the Relation To Consumed Out Of Band Contract object. * `annotation` (annotation) - (string) The annotation of the Relation To Consumed Out Of Band Contract object. * `priority` (prio) - (string) The Quality of service (QoS) priority class ID. QoS refers to the capability of a network to provide better service to selected network traffic over various technologies. The primary goal of QoS is to provide priority including dedicated bandwidth, controlled jitter and latency (required by some real-time and interactive traffic), and improved loss characteristics. You can configure the bandwidth of each QoS level using QoS profiles. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/relation_to_fallback_route_group.md b/docs/data-sources/relation_to_fallback_route_group.md index a74c9d414..da9da0235 100644 --- a/docs/data-sources/relation_to_fallback_route_group.md +++ b/docs/data-sources/relation_to_fallback_route_group.md @@ -49,3 +49,11 @@ data "aci_relation_to_fallback_route_group" "example_l3_outside" { * `id` - (string) The distinguished name (DN) of the Relation To Fallback Route Group object. * `annotation` (annotation) - (string) The annotation of the Relation To Fallback Route Group object. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/vrf_fallback_route_group.md b/docs/data-sources/vrf_fallback_route_group.md index ed3f39169..03c295100 100644 --- a/docs/data-sources/vrf_fallback_route_group.md +++ b/docs/data-sources/vrf_fallback_route_group.md @@ -58,3 +58,11 @@ data "aci_vrf_fallback_route_group" "example_vrf" { * `name` (name) - (string) The name of the VRF Fallback Route Group Member object. * `name_alias` (nameAlias) - (string) The name alias of the VRF Fallback Route Group Member object. * `fallback_member` (rnhAddr) - (string) The address of the VRF Fallback Route Group Member object. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/data-sources/vrf_fallback_route_group_member.md b/docs/data-sources/vrf_fallback_route_group_member.md index b39ca3340..11d8a2c17 100644 --- a/docs/data-sources/vrf_fallback_route_group_member.md +++ b/docs/data-sources/vrf_fallback_route_group_member.md @@ -52,3 +52,11 @@ data "aci_vrf_fallback_route_group_member" "example_vrf_fallback_route_group" { * `description` (descr) - (string) The description of the VRF Fallback Route Group Member object. * `name` (name) - (string) The name of the VRF Fallback Route Group Member object. * `name_alias` (nameAlias) - (string) The name alias of the VRF Fallback Route Group Member object. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). This attribute is supported in ACI versions: 3.2(1l) and later. + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. diff --git a/docs/resources/endpoint_tag_ip.md b/docs/resources/endpoint_tag_ip.md index edb78f5a9..369bbb796 100644 --- a/docs/resources/endpoint_tag_ip.md +++ b/docs/resources/endpoint_tag_ip.md @@ -55,6 +55,18 @@ resource "aci_endpoint_tag_ip" "full_example_tenant" { ip = "10.0.0.2" name = "name" name_alias = "name_alias" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } ``` @@ -82,6 +94,20 @@ All examples for the Endpoint Tag Ip resource can be found in the [examples](htt * `name` (name) - (string) The name of the Endpoint Tag Ip object. * `name_alias` (nameAlias) - (string) The name alias of the Endpoint Tag Ip object. +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + ## Importing An existing Endpoint Tag Ip can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/endpoint_tag_mac.md b/docs/resources/endpoint_tag_mac.md index 3069a7b7f..ee16a8ce0 100644 --- a/docs/resources/endpoint_tag_mac.md +++ b/docs/resources/endpoint_tag_mac.md @@ -55,6 +55,18 @@ resource "aci_endpoint_tag_mac" "full_example_tenant" { mac = "00:00:00:00:00:01" name = "name" name_alias = "name_alias" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } ``` @@ -82,6 +94,20 @@ All examples for the Endpoint Tag Mac resource can be found in the [examples](ht * `name` (name) - (string) The name of the Endpoint Tag Mac object. * `name_alias` (nameAlias) - (string) The name alias of the Endpoint Tag Mac object. +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + ## Importing An existing Endpoint Tag Mac can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/external_management_network_instance_profile.md b/docs/resources/external_management_network_instance_profile.md index 5ee35b4a2..17c562f06 100644 --- a/docs/resources/external_management_network_instance_profile.md +++ b/docs/resources/external_management_network_instance_profile.md @@ -58,6 +58,18 @@ resource "aci_external_management_network_instance_profile" "full_example" { out_of_band_contract_name = aci_out_of_band_contract.example.name } ] + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } ``` @@ -98,6 +110,20 @@ All examples for the External Management Network Instance Profile resource can b - Default: `unspecified` - Valid Values: `level1`, `level2`, `level3`, `level4`, `level5`, `level6`, `unspecified`. +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + ## Importing An existing External Management Network Instance Profile can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/external_management_network_subnet.md b/docs/resources/external_management_network_subnet.md index 9ae8a43f0..92432a2dd 100644 --- a/docs/resources/external_management_network_subnet.md +++ b/docs/resources/external_management_network_subnet.md @@ -53,6 +53,18 @@ resource "aci_external_management_network_subnet" "full_example_external_managem ip = "1.1.1.0/24" name = "name" name_alias = "name_alias" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } ``` @@ -79,6 +91,20 @@ All examples for the External Management Network Subnet resource can be found in * `name` (name) - (string) The name of the External Management Network Subnet object. * `name_alias` (nameAlias) - (string) The name alias of the External Management Network Subnet object. +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + ## Importing An existing External Management Network Subnet can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/l3out_consumer_label.md b/docs/resources/l3out_consumer_label.md index f3fd0ee39..1cb74b2f5 100644 --- a/docs/resources/l3out_consumer_label.md +++ b/docs/resources/l3out_consumer_label.md @@ -58,6 +58,18 @@ resource "aci_l3out_consumer_label" "full_example_l3_outside" { owner_key = "owner_key" owner_tag = "owner_tag" tag = "lemon-chiffon" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } ``` @@ -90,6 +102,20 @@ All examples for the L3out Consumer Label resource can be found in the [examples * `tag` (tag) - (string) Specifies the color of a policy label. - Valid Values: `alice-blue`, `antique-white`, `aqua`, `aquamarine`, `azure`, `beige`, `bisque`, `black`, `blanched-almond`, `blue`, `blue-violet`, `brown`, `burlywood`, `cadet-blue`, `chartreuse`, `chocolate`, `coral`, `cornflower-blue`, `cornsilk`, `crimson`, `cyan`, `dark-blue`, `dark-cyan`, `dark-goldenrod`, `dark-gray`, `dark-green`, `dark-khaki`, `dark-magenta`, `dark-olive-green`, `dark-orange`, `dark-orchid`, `dark-red`, `dark-salmon`, `dark-sea-green`, `dark-slate-blue`, `dark-slate-gray`, `dark-turquoise`, `dark-violet`, `deep-pink`, `deep-sky-blue`, `dim-gray`, `dodger-blue`, `fire-brick`, `floral-white`, `forest-green`, `fuchsia`, `gainsboro`, `ghost-white`, `gold`, `goldenrod`, `gray`, `green`, `green-yellow`, `honeydew`, `hot-pink`, `indian-red`, `indigo`, `ivory`, `khaki`, `lavender`, `lavender-blush`, `lawn-green`, `lemon-chiffon`, `light-blue`, `light-coral`, `light-cyan`, `light-goldenrod-yellow`, `light-gray`, `light-green`, `light-pink`, `light-salmon`, `light-sea-green`, `light-sky-blue`, `light-slate-gray`, `light-steel-blue`, `light-yellow`, `lime`, `lime-green`, `linen`, `magenta`, `maroon`, `medium-aquamarine`, `medium-blue`, `medium-orchid`, `medium-purple`, `medium-sea-green`, `medium-slate-blue`, `medium-spring-green`, `medium-turquoise`, `medium-violet-red`, `midnight-blue`, `mint-cream`, `misty-rose`, `moccasin`, `navajo-white`, `navy`, `old-lace`, `olive`, `olive-drab`, `orange`, `orange-red`, `orchid`, `pale-goldenrod`, `pale-green`, `pale-turquoise`, `pale-violet-red`, `papaya-whip`, `peachpuff`, `peru`, `pink`, `plum`, `powder-blue`, `purple`, `red`, `rosy-brown`, `royal-blue`, `saddle-brown`, `salmon`, `sandy-brown`, `sea-green`, `seashell`, `sienna`, `silver`, `sky-blue`, `slate-blue`, `slate-gray`, `snow`, `spring-green`, `steel-blue`, `tan`, `teal`, `thistle`, `tomato`, `turquoise`, `violet`, `wheat`, `white`, `white-smoke`, `yellow`, `yellow-green`. +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + ## Importing An existing L3out Consumer Label can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/l3out_redistribute_policy.md b/docs/resources/l3out_redistribute_policy.md index e02e08bb6..270843a8b 100644 --- a/docs/resources/l3out_redistribute_policy.md +++ b/docs/resources/l3out_redistribute_policy.md @@ -52,6 +52,18 @@ resource "aci_l3out_redistribute_policy" "full_example_l3_outside" { annotation = "annotation" source = "direct" route_control_profile_name = aci_route_control_profile.example.name + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } ``` @@ -77,6 +89,20 @@ All examples for the L3out Redistribute Policy resource can be found in the [exa * `annotation` (annotation) - (string) The annotation of the L3out Redistribute Policy object. - Default: `orchestrator:terraform` +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + ## Importing An existing L3out Redistribute Policy can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/out_of_band_contract.md b/docs/resources/out_of_band_contract.md index 047ac4817..2f04bbf76 100644 --- a/docs/resources/out_of_band_contract.md +++ b/docs/resources/out_of_band_contract.md @@ -56,6 +56,18 @@ resource "aci_out_of_band_contract" "full_example" { priority = "level1" scope = "application-profile" target_dscp = "AF11" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } ``` @@ -93,6 +105,20 @@ All examples for the Out Of Band Contract resource can be found in the [examples - Default: `unspecified` - Valid Values: `AF11`, `AF12`, `AF13`, `AF21`, `AF22`, `AF23`, `AF31`, `AF32`, `AF33`, `AF41`, `AF42`, `AF43`, `CS0`, `CS1`, `CS2`, `CS3`, `CS4`, `CS5`, `CS6`, `CS7`, `EF`, `VA`, `unspecified`. +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + ## Importing An existing Out Of Band Contract can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/pim_route_map_entry.md b/docs/resources/pim_route_map_entry.md index eb284d82c..0656563e3 100644 --- a/docs/resources/pim_route_map_entry.md +++ b/docs/resources/pim_route_map_entry.md @@ -57,6 +57,18 @@ resource "aci_pim_route_map_entry" "full_example_pim_route_map_policy" { order = "1" rendezvous_point_ip = "0.0.0.0" source_ip = "1.1.1.1/30" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } ``` @@ -89,6 +101,20 @@ All examples for the Pim Route Map Entry resource can be found in the [examples] * `rendezvous_point_ip` (rp) - (string) The rendezvous point ip of the Pim Route Map Entry object. * `source_ip` (src) - (string) The source ip of the Pim Route Map Entry object. +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + ## Importing An existing Pim Route Map Entry can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/pim_route_map_policy.md b/docs/resources/pim_route_map_policy.md index c44f7dbc4..ab3d1c569 100644 --- a/docs/resources/pim_route_map_policy.md +++ b/docs/resources/pim_route_map_policy.md @@ -54,6 +54,18 @@ resource "aci_pim_route_map_policy" "full_example_tenant" { name_alias = "name_alias" owner_key = "owner_key" owner_tag = "owner_tag" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } ``` @@ -81,6 +93,20 @@ All examples for the Pim Route Map Policy resource can be found in the [examples * `owner_key` (ownerKey) - (string) The key for enabling clients to own their data for entity correlation. * `owner_tag` (ownerTag) - (string) A tag for enabling clients to add their own data. For example, to indicate who created this object. +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + ## Importing An existing Pim Route Map Policy can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/relation_to_consumed_out_of_band_contract.md b/docs/resources/relation_to_consumed_out_of_band_contract.md index d825b458b..f9244a156 100644 --- a/docs/resources/relation_to_consumed_out_of_band_contract.md +++ b/docs/resources/relation_to_consumed_out_of_band_contract.md @@ -51,6 +51,18 @@ resource "aci_relation_to_consumed_out_of_band_contract" "full_example_external_ annotation = "annotation" priority = "level1" out_of_band_contract_name = aci_out_of_band_contract.example.name + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } ``` @@ -77,6 +89,20 @@ All examples for the Relation To Consumed Out Of Band Contract resource can be f - Default: `unspecified` - Valid Values: `level1`, `level2`, `level3`, `level4`, `level5`, `level6`, `unspecified`. +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + ## Importing An existing Relation To Consumed Out Of Band Contract can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/relation_to_fallback_route_group.md b/docs/resources/relation_to_fallback_route_group.md index db02e08cf..c7acf8bd1 100644 --- a/docs/resources/relation_to_fallback_route_group.md +++ b/docs/resources/relation_to_fallback_route_group.md @@ -50,6 +50,18 @@ resource "aci_relation_to_fallback_route_group" "full_example_l3_outside" { parent_dn = aci_l3_outside.example.id annotation = "annotation" target_dn = aci_vrf_fallback_route_group.test.id + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } ``` @@ -73,6 +85,20 @@ All examples for the Relation To Fallback Route Group resource can be found in t * `annotation` (annotation) - (string) The annotation of the Relation To Fallback Route Group object. - Default: `orchestrator:terraform` +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + ## Importing An existing Relation To Fallback Route Group can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/vrf_fallback_route_group.md b/docs/resources/vrf_fallback_route_group.md index c3db9c4f6..dbfacd95f 100644 --- a/docs/resources/vrf_fallback_route_group.md +++ b/docs/resources/vrf_fallback_route_group.md @@ -61,6 +61,18 @@ resource "aci_vrf_fallback_route_group" "full_example_vrf" { fallback_member = "2.2.2.2" } ] + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } ``` @@ -100,6 +112,20 @@ All examples for the VRF Fallback Route Group resource can be found in the [exam * `name` (name) - (string) The name of the VRF Fallback Route Group Member object. * `name_alias` (nameAlias) - (string) The name alias of the VRF Fallback Route Group Member object. +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + ## Importing An existing VRF Fallback Route Group can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/docs/resources/vrf_fallback_route_group_member.md b/docs/resources/vrf_fallback_route_group_member.md index 401aa0ed7..5a056816e 100644 --- a/docs/resources/vrf_fallback_route_group_member.md +++ b/docs/resources/vrf_fallback_route_group_member.md @@ -54,6 +54,18 @@ resource "aci_vrf_fallback_route_group_member" "full_example_vrf_fallback_route_ name = "name" name_alias = "name_alias" fallback_member = "2.2.2.3" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } ``` @@ -80,6 +92,20 @@ All examples for the VRF Fallback Route Group Member resource can be found in th * `name` (name) - (string) The name of the VRF Fallback Route Group Member object. * `name_alias` (nameAlias) - (string) The name alias of the VRF Fallback Route Group Member object. +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + ## Importing An existing VRF Fallback Route Group Member can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: diff --git a/examples/resources/aci_endpoint_tag_ip/resource-all-attributes.tf b/examples/resources/aci_endpoint_tag_ip/resource-all-attributes.tf index 35fe480cc..847c24241 100644 --- a/examples/resources/aci_endpoint_tag_ip/resource-all-attributes.tf +++ b/examples/resources/aci_endpoint_tag_ip/resource-all-attributes.tf @@ -7,4 +7,16 @@ resource "aci_endpoint_tag_ip" "full_example_tenant" { ip = "10.0.0.2" name = "name" name_alias = "name_alias" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } diff --git a/examples/resources/aci_endpoint_tag_mac/resource-all-attributes.tf b/examples/resources/aci_endpoint_tag_mac/resource-all-attributes.tf index a1ba38d8c..cb5fcf1f3 100644 --- a/examples/resources/aci_endpoint_tag_mac/resource-all-attributes.tf +++ b/examples/resources/aci_endpoint_tag_mac/resource-all-attributes.tf @@ -7,4 +7,16 @@ resource "aci_endpoint_tag_mac" "full_example_tenant" { mac = "00:00:00:00:00:01" name = "name" name_alias = "name_alias" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } diff --git a/examples/resources/aci_external_management_network_instance_profile/resource-all-attributes.tf b/examples/resources/aci_external_management_network_instance_profile/resource-all-attributes.tf index 321155433..55b9ca15a 100644 --- a/examples/resources/aci_external_management_network_instance_profile/resource-all-attributes.tf +++ b/examples/resources/aci_external_management_network_instance_profile/resource-all-attributes.tf @@ -12,4 +12,16 @@ resource "aci_external_management_network_instance_profile" "full_example" { out_of_band_contract_name = aci_out_of_band_contract.example.name } ] + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } diff --git a/examples/resources/aci_external_management_network_subnet/resource-all-attributes.tf b/examples/resources/aci_external_management_network_subnet/resource-all-attributes.tf index d5186529c..95e868212 100644 --- a/examples/resources/aci_external_management_network_subnet/resource-all-attributes.tf +++ b/examples/resources/aci_external_management_network_subnet/resource-all-attributes.tf @@ -6,4 +6,16 @@ resource "aci_external_management_network_subnet" "full_example_external_managem ip = "1.1.1.0/24" name = "name" name_alias = "name_alias" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } diff --git a/examples/resources/aci_l3out_consumer_label/resource-all-attributes.tf b/examples/resources/aci_l3out_consumer_label/resource-all-attributes.tf index 605ce7b03..09a5c84eb 100644 --- a/examples/resources/aci_l3out_consumer_label/resource-all-attributes.tf +++ b/examples/resources/aci_l3out_consumer_label/resource-all-attributes.tf @@ -9,4 +9,16 @@ resource "aci_l3out_consumer_label" "full_example_l3_outside" { owner_key = "owner_key" owner_tag = "owner_tag" tag = "lemon-chiffon" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } diff --git a/examples/resources/aci_l3out_redistribute_policy/resource-all-attributes.tf b/examples/resources/aci_l3out_redistribute_policy/resource-all-attributes.tf index cbb24119d..65ac30034 100644 --- a/examples/resources/aci_l3out_redistribute_policy/resource-all-attributes.tf +++ b/examples/resources/aci_l3out_redistribute_policy/resource-all-attributes.tf @@ -4,4 +4,16 @@ resource "aci_l3out_redistribute_policy" "full_example_l3_outside" { annotation = "annotation" source = "direct" route_control_profile_name = aci_route_control_profile.example.name + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } diff --git a/examples/resources/aci_out_of_band_contract/resource-all-attributes.tf b/examples/resources/aci_out_of_band_contract/resource-all-attributes.tf index 092e6104c..293499941 100644 --- a/examples/resources/aci_out_of_band_contract/resource-all-attributes.tf +++ b/examples/resources/aci_out_of_band_contract/resource-all-attributes.tf @@ -10,4 +10,16 @@ resource "aci_out_of_band_contract" "full_example" { priority = "level1" scope = "application-profile" target_dscp = "AF11" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } diff --git a/examples/resources/aci_pim_route_map_entry/resource-all-attributes.tf b/examples/resources/aci_pim_route_map_entry/resource-all-attributes.tf index b2f732235..c3e6636ed 100644 --- a/examples/resources/aci_pim_route_map_entry/resource-all-attributes.tf +++ b/examples/resources/aci_pim_route_map_entry/resource-all-attributes.tf @@ -10,4 +10,16 @@ resource "aci_pim_route_map_entry" "full_example_pim_route_map_policy" { order = "1" rendezvous_point_ip = "0.0.0.0" source_ip = "1.1.1.1/30" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } diff --git a/examples/resources/aci_pim_route_map_policy/resource-all-attributes.tf b/examples/resources/aci_pim_route_map_policy/resource-all-attributes.tf index d1fe02c69..76766aaf0 100644 --- a/examples/resources/aci_pim_route_map_policy/resource-all-attributes.tf +++ b/examples/resources/aci_pim_route_map_policy/resource-all-attributes.tf @@ -7,4 +7,16 @@ resource "aci_pim_route_map_policy" "full_example_tenant" { name_alias = "name_alias" owner_key = "owner_key" owner_tag = "owner_tag" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } diff --git a/examples/resources/aci_relation_to_consumed_out_of_band_contract/resource-all-attributes.tf b/examples/resources/aci_relation_to_consumed_out_of_band_contract/resource-all-attributes.tf index 3b9ab8e11..da51cd5a4 100644 --- a/examples/resources/aci_relation_to_consumed_out_of_band_contract/resource-all-attributes.tf +++ b/examples/resources/aci_relation_to_consumed_out_of_band_contract/resource-all-attributes.tf @@ -4,4 +4,16 @@ resource "aci_relation_to_consumed_out_of_band_contract" "full_example_external_ annotation = "annotation" priority = "level1" out_of_band_contract_name = aci_out_of_band_contract.example.name + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } diff --git a/examples/resources/aci_relation_to_fallback_route_group/resource-all-attributes.tf b/examples/resources/aci_relation_to_fallback_route_group/resource-all-attributes.tf index 9046e1796..34cbde73b 100644 --- a/examples/resources/aci_relation_to_fallback_route_group/resource-all-attributes.tf +++ b/examples/resources/aci_relation_to_fallback_route_group/resource-all-attributes.tf @@ -3,4 +3,16 @@ resource "aci_relation_to_fallback_route_group" "full_example_l3_outside" { parent_dn = aci_l3_outside.example.id annotation = "annotation" target_dn = aci_vrf_fallback_route_group.test.id + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } diff --git a/examples/resources/aci_vrf_fallback_route_group/resource-all-attributes.tf b/examples/resources/aci_vrf_fallback_route_group/resource-all-attributes.tf index 27a95bd47..b62d8fdf0 100644 --- a/examples/resources/aci_vrf_fallback_route_group/resource-all-attributes.tf +++ b/examples/resources/aci_vrf_fallback_route_group/resource-all-attributes.tf @@ -14,4 +14,16 @@ resource "aci_vrf_fallback_route_group" "full_example_vrf" { fallback_member = "2.2.2.2" } ] + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } diff --git a/examples/resources/aci_vrf_fallback_route_group_member/resource-all-attributes.tf b/examples/resources/aci_vrf_fallback_route_group_member/resource-all-attributes.tf index 77f4de9ac..bea43151d 100644 --- a/examples/resources/aci_vrf_fallback_route_group_member/resource-all-attributes.tf +++ b/examples/resources/aci_vrf_fallback_route_group_member/resource-all-attributes.tf @@ -6,4 +6,16 @@ resource "aci_vrf_fallback_route_group_member" "full_example_vrf_fallback_route_ name = "name" name_alias = "name_alias" fallback_member = "2.2.2.3" + annotations = [ + { + key = "key_0" + value = "value_1" + } + ] + tags = [ + { + key = "key_0" + value = "value_1" + } + ] } diff --git a/gen/definitions/classes.yaml b/gen/definitions/classes.yaml index 4ee550d71..f6a79014b 100644 --- a/gen/definitions/classes.yaml +++ b/gen/definitions/classes.yaml @@ -223,13 +223,13 @@ commPol: contained_by: - "polUni" rn_prepend: "fabric" - children: - - tagAnnotation - - tagTag + # children: + # - tagAnnotation + # - tagTag -commHttps: - children: - - tagAnnotation +# commHttps: +# children: +# - tagAnnotation # - tagTag # commRsKeyRing: diff --git a/gen/generator.go b/gen/generator.go index fc460ba14..1c706bc3b 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -112,7 +112,7 @@ var duplicateLabels = []string{} var resourceNames = map[string]string{} var rnPrefix = map[string]string{} var targetRelationalPropertyClasses = map[string]string{} -var alwaysIncludeChildren = []string{} +var alwaysIncludeChildren = []string{"tag:Annotation", "tag:Tag"} var excludeChildResourceNamesFromDocs = []string{"", "annotation", "tag"} func GetResourceNameAsDescription(s string, definitions Definitions) string { diff --git a/gen/templates/resource.go.tmpl b/gen/templates/resource.go.tmpl index 86c9bbd5e..bc81fc4d5 100644 --- a/gen/templates/resource.go.tmpl +++ b/gen/templates/resource.go.tmpl @@ -781,7 +781,7 @@ func {{.ResourceClassName}}{{.ParentHierarchy}}ResourceModelAttributeTypes() map {{- end}} {{- end}} {{- range .Children}} - "{{ .ResourceName }}": types.SetType{ElemType: types.StringType}, + "{{ .ResourceName }}": types.SetType{ElemType: {{.ResourceClassName}}{{.ParentHierarchy}}ResourceModelElementType()}, {{- end}} } } @@ -865,6 +865,9 @@ func {{.ResourceClassName}}{{.ParentHierarchy}}ResourceModelElementType() attr.T {{$grandChild:= .}} var {{.PkgName}}{{.ParentHierarchy}}Plan, {{.PkgName}}{{.ParentHierarchy}}State []{{.ResourceClassName}}{{.ParentHierarchy}}ResourceModel {{.ParentHierarchy | lowerFirstCharacter}}.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}{{.ParentHierarchy}}Plan, false) +for _, {{ .PkgName }}{{.ParentHierarchy}}state := range {{.ParentHierarchy | lowerFirstCharacter}}State { + {{ .PkgName }}{{.ParentHierarchy}}state.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}{{.ParentHierarchy}}State, false) +} if !{{ .ParentHierarchy | lowerFirstCharacter}}.{{.ResourceClassName}}.IsNull() && !{{ .ParentHierarchy | lowerFirstCharacter}}.{{.ResourceClassName}}.IsUnknown(){ {{- if .IdentifiedBy}} {{ .PkgName }}Identifiers := []{{.ResourceClassName}}Identifier{} @@ -886,9 +889,17 @@ for _, {{ .PkgName }}{{.ParentHierarchy}} := range {{.PkgName}}{{.ParentHierarch {{.PkgName}}{{$.ParentHierarchy}}ChildMap.Attributes["annotation"] = globalAnnotation } {{- end}} {{- end}} + {{- $enteredGreatGrandChildPayloadZone := false }} {{- range .Children}} + {{- $enteredGreatGrandChildPayloadZone = true }} {{- template "grandChildPayload" . }} {{- end}} + {{- range .Children}} + {{- if $enteredGreatGrandChildPayloadZone }} + {{- $enteredGreatGrandChildPayloadZone = false }} + {{$.PkgName}}{{$.ParentHierarchy}}ChildMap.Children = {{.ParentHierarchy}}Children + {{- end}} + {{- end}} {{ .ParentHierarchy }}Children = append({{ .ParentHierarchy }}Children, map[string]interface{}{"{{.PkgName}}": {{.PkgName}}{{$.ParentHierarchy}}ChildMap}) {{- if .IdentifiedBy}} {{ .PkgName }}Identifier := {{ .ResourceClassName }}Identifier{} @@ -901,36 +912,31 @@ for _, {{ .PkgName }}{{.ParentHierarchy}} := range {{.PkgName}}{{.ParentHierarch {{- end}} } {{- if .IdentifiedBy}} - for _, {{ .PkgName }}{{.ParentHierarchy}}state := range {{.ParentHierarchy | lowerFirstCharacter}}State { - {{ .PkgName }}{{.ParentHierarchy}}state.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}{{.ParentHierarchy}}State, false) - for _, {{ .PkgName }}{{.ParentHierarchy}} := range {{ .PkgName }}{{.ParentHierarchy}}State { - delete := true - for _, {{ .PkgName }}Identifier := range {{ .PkgName }}Identifiers { {{$i := 1}}{{$length := len .IdentifiedBy}} - if - {{- range .Properties}} - {{- if .IsNaming }} - {{ .PkgName }}Identifier.{{.Name}} == {{ .PkgName }}{{$grandChild.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}{{- if ne $length $i}} {{$i = add $i 1}} && {{- end}} - {{- end}} - {{- end}} { - delete = false - break - } - } - if delete { - {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete := NewAciObject() - {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete.Attributes["status"] = "deleted" + for _, {{ .PkgName }}{{.ParentHierarchy}} := range {{ .PkgName }}{{.ParentHierarchy}}State { + delete := true + for _, {{ .PkgName }}Identifier := range {{ .PkgName }}Identifiers { {{$i := 1}}{{$length := len .IdentifiedBy}} + if {{- range .Properties}} {{- if .IsNaming }} - {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete.Attributes["{{.PropertyName}}"] = {{ .PkgName }}{{$grandChild.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.ValueString() + {{ .PkgName }}Identifier.{{.Name}} == {{ .PkgName }}{{$grandChild.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}{{- if ne $length $i}} {{$i = add $i 1}} && {{- end}} {{- end}} - {{- end}} - {{ .ParentHierarchy }}Children = append({{ .ParentHierarchy }}Children, map[string]interface{}{"{{ .PkgName }}": {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete}) + {{- end}} { + delete = false + break } } + if delete { + {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete := NewAciObject() + {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete.Attributes["status"] = "deleted" + {{- range .Properties}} + {{- if .IsNaming }} + {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete.Attributes["{{.PropertyName}}"] = {{ .PkgName }}{{$grandChild.ParentHierarchy}}.{{- if eq .Name "Id"}}{{.ResourceClassName}}{{ .Name }}{{- else}}{{.Name}}{{- end}}.ValueString() + {{- end}} + {{- end}} + {{ .ParentHierarchy }}Children = append({{ .ParentHierarchy }}Children, map[string]interface{}{"{{ .PkgName }}": {{.PkgName}}{{$.ParentHierarchy}}ChildMapForDelete}) + } } - {{- else}} - for _, {{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}}State := range {{.ParentHierarchy | lowerFirstCharacter}}State { - {{.ParentName | lowerFirstCharacter}}{{.ResourceClassName | lowerFirstCharacter}}State.{{.ResourceClassName}}.ElementsAs(ctx, &{{.PkgName}}{{.ParentHierarchy}}State, false) + {{- else}} if len({{ .PkgName }}{{.ParentHierarchy}}Plan) == 0 && len({{.PkgName}}{{.ParentHierarchy}}State) == 1 { {{- if .AllowDelete}} {{.PkgName}}{{.ParentHierarchy}}ChildMap := NewAciObject() @@ -944,7 +950,6 @@ for _, {{ .PkgName }}{{.ParentHierarchy}} := range {{.PkgName}}{{.ParentHierarch return nil {{- end }} } - } {{- end }} } {{- end }} diff --git a/gen/testvars/fvEpIpTag.yaml b/gen/testvars/fvEpIpTag.yaml index 6d855ede7..07b6c2485 100644 --- a/gen/testvars/fvEpIpTag.yaml +++ b/gen/testvars/fvEpIpTag.yaml @@ -26,6 +26,21 @@ all: name: "name" name_alias: "name_alias" +children: + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + parents: - class_name: "fvTenant" parent_dependency: "" diff --git a/gen/testvars/fvEpMacTag.yaml b/gen/testvars/fvEpMacTag.yaml index 6afbe9ad1..5c4298d7f 100644 --- a/gen/testvars/fvEpMacTag.yaml +++ b/gen/testvars/fvEpMacTag.yaml @@ -26,6 +26,21 @@ all: name: "name" name_alias: "name_alias" +children: + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + parents: - class_name: "fvTenant" parent_dependency: "" diff --git a/gen/testvars/fvFBRGroup.yaml b/gen/testvars/fvFBRGroup.yaml index e6c0860b3..8fd06febd 100644 --- a/gen/testvars/fvFBRGroup.yaml +++ b/gen/testvars/fvFBRGroup.yaml @@ -35,6 +35,20 @@ children: name_alias: "name_alias_2" fallback_member: "2.2.2.3" + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + parents: - class_name: "fvCtx" parent_dependency: "fvTenant" diff --git a/gen/testvars/fvFBRMember.yaml b/gen/testvars/fvFBRMember.yaml index 34ab51313..218e652f2 100644 --- a/gen/testvars/fvFBRMember.yaml +++ b/gen/testvars/fvFBRMember.yaml @@ -23,6 +23,21 @@ all: name: "name" name_alias: "name_alias" +children: + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + parents: - class_name: "fvFBRGroup" parent_dependency: "fvCtx" diff --git a/gen/testvars/l3extConsLbl.yaml b/gen/testvars/l3extConsLbl.yaml index e32d8d4c1..fabbd89ac 100644 --- a/gen/testvars/l3extConsLbl.yaml +++ b/gen/testvars/l3extConsLbl.yaml @@ -29,6 +29,21 @@ all: owner_tag: "owner_tag" tag: "lemon-chiffon" +children: + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + parents: - class_name: "l3extOut" parent_dependency: "" diff --git a/gen/testvars/l3extRsOutToFBRGroup.yaml b/gen/testvars/l3extRsOutToFBRGroup.yaml index 4f2bfd547..12a6716b9 100644 --- a/gen/testvars/l3extRsOutToFBRGroup.yaml +++ b/gen/testvars/l3extRsOutToFBRGroup.yaml @@ -17,6 +17,21 @@ resource_required: all: annotation: "annotation" +children: + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + parents: - class_name: "l3extOut" parent_dependency: "fvTenant" diff --git a/gen/testvars/l3extRsRedistributePol.yaml b/gen/testvars/l3extRsRedistributePol.yaml index f13c9c2c3..fcd38f5b5 100644 --- a/gen/testvars/l3extRsRedistributePol.yaml +++ b/gen/testvars/l3extRsRedistributePol.yaml @@ -22,6 +22,21 @@ all: annotation: "annotation" source: "direct" +children: + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + parents: - class_name: "l3extOut" parent_dependency: "fvTenant" diff --git a/gen/testvars/mgmtInstP.yaml b/gen/testvars/mgmtInstP.yaml index 7c915eaea..a2c1874a2 100644 --- a/gen/testvars/mgmtInstP.yaml +++ b/gen/testvars/mgmtInstP.yaml @@ -33,3 +33,17 @@ children: priority: "level2" out_of_band_contract_name: "out_of_band_contract_name_1" + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + diff --git a/gen/testvars/mgmtRsOoBCons.yaml b/gen/testvars/mgmtRsOoBCons.yaml index ff08401f0..301687bba 100644 --- a/gen/testvars/mgmtRsOoBCons.yaml +++ b/gen/testvars/mgmtRsOoBCons.yaml @@ -19,6 +19,21 @@ all: annotation: "annotation" priority: "level1" +children: + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + parents: - class_name: "mgmtInstP" parent_dependency: "" diff --git a/gen/testvars/mgmtSubnet.yaml b/gen/testvars/mgmtSubnet.yaml index b37e5a836..b7280633a 100644 --- a/gen/testvars/mgmtSubnet.yaml +++ b/gen/testvars/mgmtSubnet.yaml @@ -23,6 +23,21 @@ all: name: "name" name_alias: "name_alias" +children: + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + parents: - class_name: "mgmtInstP" parent_dependency: "" diff --git a/gen/testvars/pimRouteMapEntry.yaml b/gen/testvars/pimRouteMapEntry.yaml index 7b5ea9d43..bfdfb090d 100644 --- a/gen/testvars/pimRouteMapEntry.yaml +++ b/gen/testvars/pimRouteMapEntry.yaml @@ -31,6 +31,21 @@ all: rendezvous_point_ip: "0.0.0.0" source_ip: "1.1.1.1/30" +children: + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + parents: - class_name: "pimRouteMapPol" parent_dependency: "fvTenant" diff --git a/gen/testvars/pimRouteMapPol.yaml b/gen/testvars/pimRouteMapPol.yaml index 51d708005..cac7fd60c 100644 --- a/gen/testvars/pimRouteMapPol.yaml +++ b/gen/testvars/pimRouteMapPol.yaml @@ -25,6 +25,21 @@ all: owner_key: "owner_key" owner_tag: "owner_tag" +children: + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + parents: - class_name: "fvTenant" parent_dependency: "" diff --git a/gen/testvars/vzOOBBrCP.yaml b/gen/testvars/vzOOBBrCP.yaml index 418042e4e..2c6696909 100644 --- a/gen/testvars/vzOOBBrCP.yaml +++ b/gen/testvars/vzOOBBrCP.yaml @@ -33,3 +33,18 @@ all: scope: "application-profile" target_dscp: "AF11" +children: + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + diff --git a/internal/provider/data_source_aci_endpoint_tag_ip.go b/internal/provider/data_source_aci_endpoint_tag_ip.go index 814d8978a..7c1bf4a91 100644 --- a/internal/provider/data_source_aci_endpoint_tag_ip.go +++ b/internal/provider/data_source_aci_endpoint_tag_ip.go @@ -72,6 +72,38 @@ func (d *FvEpIpTagDataSource) Schema(ctx context.Context, req datasource.SchemaR Computed: true, MarkdownDescription: `The name alias of the Endpoint Tag Ip object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of datasource: aci_endpoint_tag_ip") diff --git a/internal/provider/data_source_aci_endpoint_tag_mac.go b/internal/provider/data_source_aci_endpoint_tag_mac.go index 2395357de..20681e3c3 100644 --- a/internal/provider/data_source_aci_endpoint_tag_mac.go +++ b/internal/provider/data_source_aci_endpoint_tag_mac.go @@ -72,6 +72,38 @@ func (d *FvEpMacTagDataSource) Schema(ctx context.Context, req datasource.Schema Computed: true, MarkdownDescription: `The name alias of the Endpoint Tag Mac object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of datasource: aci_endpoint_tag_mac") diff --git a/internal/provider/data_source_aci_external_management_network_instance_profile.go b/internal/provider/data_source_aci_external_management_network_instance_profile.go index dc75b8340..4c1859580 100644 --- a/internal/provider/data_source_aci_external_management_network_instance_profile.go +++ b/internal/provider/data_source_aci_external_management_network_instance_profile.go @@ -84,6 +84,38 @@ func (d *MgmtInstPDataSource) Schema(ctx context.Context, req datasource.SchemaR }, }, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of datasource: aci_external_management_network_instance_profile") diff --git a/internal/provider/data_source_aci_external_management_network_subnet.go b/internal/provider/data_source_aci_external_management_network_subnet.go index 0edf2a502..c14f87be2 100644 --- a/internal/provider/data_source_aci_external_management_network_subnet.go +++ b/internal/provider/data_source_aci_external_management_network_subnet.go @@ -68,6 +68,38 @@ func (d *MgmtSubnetDataSource) Schema(ctx context.Context, req datasource.Schema Computed: true, MarkdownDescription: `The name alias of the External Management Network Subnet object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of datasource: aci_external_management_network_subnet") diff --git a/internal/provider/data_source_aci_l3out_consumer_label.go b/internal/provider/data_source_aci_l3out_consumer_label.go index 64baf147a..8781de9e8 100644 --- a/internal/provider/data_source_aci_l3out_consumer_label.go +++ b/internal/provider/data_source_aci_l3out_consumer_label.go @@ -80,6 +80,38 @@ func (d *L3extConsLblDataSource) Schema(ctx context.Context, req datasource.Sche Computed: true, MarkdownDescription: `Specifies the color of a policy label.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of datasource: aci_l3out_consumer_label") diff --git a/internal/provider/data_source_aci_l3out_redistribute_policy.go b/internal/provider/data_source_aci_l3out_redistribute_policy.go index 2c72a39c1..63f2003f1 100644 --- a/internal/provider/data_source_aci_l3out_redistribute_policy.go +++ b/internal/provider/data_source_aci_l3out_redistribute_policy.go @@ -60,6 +60,38 @@ func (d *L3extRsRedistributePolDataSource) Schema(ctx context.Context, req datas Required: true, MarkdownDescription: `The name of the Route Control Profile object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of datasource: aci_l3out_redistribute_policy") diff --git a/internal/provider/data_source_aci_out_of_band_contract.go b/internal/provider/data_source_aci_out_of_band_contract.go index bb5a9f0f3..28c567b69 100644 --- a/internal/provider/data_source_aci_out_of_band_contract.go +++ b/internal/provider/data_source_aci_out_of_band_contract.go @@ -84,6 +84,38 @@ func (d *VzOOBBrCPDataSource) Schema(ctx context.Context, req datasource.SchemaR Computed: true, MarkdownDescription: `The target DSCP value of the Out Of Band Contract object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of datasource: aci_out_of_band_contract") diff --git a/internal/provider/data_source_aci_pim_route_map_entry.go b/internal/provider/data_source_aci_pim_route_map_entry.go index b438d7853..4df1c989f 100644 --- a/internal/provider/data_source_aci_pim_route_map_entry.go +++ b/internal/provider/data_source_aci_pim_route_map_entry.go @@ -84,6 +84,38 @@ func (d *PimRouteMapEntryDataSource) Schema(ctx context.Context, req datasource. Computed: true, MarkdownDescription: `The source ip of the Pim Route Map Entry object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of datasource: aci_pim_route_map_entry") diff --git a/internal/provider/data_source_aci_pim_route_map_policy.go b/internal/provider/data_source_aci_pim_route_map_policy.go index 2227e0c4a..4959e5239 100644 --- a/internal/provider/data_source_aci_pim_route_map_policy.go +++ b/internal/provider/data_source_aci_pim_route_map_policy.go @@ -72,6 +72,38 @@ func (d *PimRouteMapPolDataSource) Schema(ctx context.Context, req datasource.Sc Computed: true, MarkdownDescription: `A tag for enabling clients to add their own data. For example, to indicate who created this object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of datasource: aci_pim_route_map_policy") diff --git a/internal/provider/data_source_aci_relation_to_consumed_out_of_band_contract.go b/internal/provider/data_source_aci_relation_to_consumed_out_of_band_contract.go index 92d8a8d4c..3a1f25c2e 100644 --- a/internal/provider/data_source_aci_relation_to_consumed_out_of_band_contract.go +++ b/internal/provider/data_source_aci_relation_to_consumed_out_of_band_contract.go @@ -60,6 +60,38 @@ func (d *MgmtRsOoBConsDataSource) Schema(ctx context.Context, req datasource.Sch Required: true, MarkdownDescription: `The name of the Out Of Band Contract object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of datasource: aci_relation_to_consumed_out_of_band_contract") diff --git a/internal/provider/data_source_aci_relation_to_fallback_route_group.go b/internal/provider/data_source_aci_relation_to_fallback_route_group.go index b84193cb0..43ff1992b 100644 --- a/internal/provider/data_source_aci_relation_to_fallback_route_group.go +++ b/internal/provider/data_source_aci_relation_to_fallback_route_group.go @@ -56,6 +56,38 @@ func (d *L3extRsOutToFBRGroupDataSource) Schema(ctx context.Context, req datasou Required: true, MarkdownDescription: `The distinguished name of the VRF Fallback Route Group object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of datasource: aci_relation_to_fallback_route_group") diff --git a/internal/provider/data_source_aci_vrf_fallback_route_group.go b/internal/provider/data_source_aci_vrf_fallback_route_group.go index dee8baa03..25948dd50 100644 --- a/internal/provider/data_source_aci_vrf_fallback_route_group.go +++ b/internal/provider/data_source_aci_vrf_fallback_route_group.go @@ -92,6 +92,38 @@ func (d *FvFBRGroupDataSource) Schema(ctx context.Context, req datasource.Schema }, }, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of datasource: aci_vrf_fallback_route_group") diff --git a/internal/provider/data_source_aci_vrf_fallback_route_group_member.go b/internal/provider/data_source_aci_vrf_fallback_route_group_member.go index 8cee4b87b..11bc2a747 100644 --- a/internal/provider/data_source_aci_vrf_fallback_route_group_member.go +++ b/internal/provider/data_source_aci_vrf_fallback_route_group_member.go @@ -68,6 +68,38 @@ func (d *FvFBRMemberDataSource) Schema(ctx context.Context, req datasource.Schem Required: true, MarkdownDescription: `The address of the VRF Fallback Route Group Member object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of datasource: aci_vrf_fallback_route_group_member") diff --git a/internal/provider/resource_aci_communication_policy.go b/internal/provider/resource_aci_communication_policy.go index eed1eaaee..98a5694e7 100644 --- a/internal/provider/resource_aci_communication_policy.go +++ b/internal/provider/resource_aci_communication_policy.go @@ -85,6 +85,7 @@ type CommHttpsCommPolResourceModel struct { CommRsClientCertCA types.Set `tfsdk:"tp"` CommRsKeyRing types.Set `tfsdk:"key_ring"` TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` } func CommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { @@ -111,9 +112,10 @@ func CommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { "throttle_rate": types.StringType, "throttle_st": types.StringType, "visore_access": types.StringType, - "tp": types.SetType{ElemType: types.StringType}, - "key_ring": types.SetType{ElemType: types.StringType}, - "annotations": types.SetType{ElemType: types.StringType}, + "tp": types.SetType{ElemType: CommRsClientCertCACommHttpsCommPolResourceModelElementType()}, + "key_ring": types.SetType{ElemType: CommRsKeyRingCommHttpsCommPolResourceModelElementType()}, + "annotations": types.SetType{ElemType: TagAnnotationCommHttpsCommPolResourceModelElementType()}, + "tags": types.SetType{ElemType: TagTagCommHttpsCommPolResourceModelElementType()}, } } @@ -123,14 +125,18 @@ func CommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { // CommRsClientCertCACommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. type CommRsClientCertCACommHttpsCommPolResourceModel struct { - Annotation types.String `tfsdk:"annotation"` - TDn types.String `tfsdk:"target_dn"` + Annotation types.String `tfsdk:"annotation"` + TDn types.String `tfsdk:"target_dn"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` } func CommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { return map[string]attr.Type{ - "annotation": types.StringType, - "target_dn": types.StringType, + "annotation": types.StringType, + "target_dn": types.StringType, + "annotations": types.SetType{ElemType: TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModelElementType()}, + "tags": types.SetType{ElemType: TagTagCommRsClientCertCACommHttpsCommPolResourceModelElementType()}, } } @@ -138,16 +144,54 @@ func CommRsClientCertCACommHttpsCommPolResourceModelElementType() attr.TypeWithA return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes()) } +// TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes()) +} + +// TagTagCommRsClientCertCACommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. +type TagTagCommRsClientCertCACommHttpsCommPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagCommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagCommRsClientCertCACommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagCommRsClientCertCACommHttpsCommPolResourceModelAttributeTypes()) +} + // CommRsKeyRingCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. type CommRsKeyRingCommHttpsCommPolResourceModel struct { Annotation types.String `tfsdk:"annotation"` TnPkiKeyRingName types.String `tfsdk:"tn_pki_key_ring_name"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` } func CommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { return map[string]attr.Type{ "annotation": types.StringType, "tn_pki_key_ring_name": types.StringType, + "annotations": types.SetType{ElemType: TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModelElementType()}, + "tags": types.SetType{ElemType: TagTagCommRsKeyRingCommHttpsCommPolResourceModelElementType()}, } } @@ -155,6 +199,40 @@ func CommRsKeyRingCommHttpsCommPolResourceModelElementType() attr.TypeWithAttrib return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, CommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes()) } +// TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes()) +} + +// TagTagCommRsKeyRingCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. +type TagTagCommRsKeyRingCommHttpsCommPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagCommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagCommRsKeyRingCommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagCommRsKeyRingCommHttpsCommPolResourceModelAttributeTypes()) +} + // TagAnnotationCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. type TagAnnotationCommHttpsCommPolResourceModel struct { Key types.String `tfsdk:"key"` @@ -172,6 +250,23 @@ func TagAnnotationCommHttpsCommPolResourceModelElementType() attr.TypeWithAttrib return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationCommHttpsCommPolResourceModelAttributeTypes()) } +// TagTagCommHttpsCommPolResourceModel describes the resource data model for the children without relation ships. +type TagTagCommHttpsCommPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagCommHttpsCommPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagCommHttpsCommPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagCommHttpsCommPolResourceModelAttributeTypes()) +} + // TagAnnotationCommPolResourceModel describes the resource data model for the children without relation ships. type TagAnnotationCommPolResourceModel struct { Key types.String `tfsdk:"key"` @@ -573,6 +668,62 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest }, MarkdownDescription: `The distinguished name of the target.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, }, }, @@ -606,6 +757,62 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest }, MarkdownDescription: `The HTTP connection key ring. Each PKI device holds a pair of asymmetric Rivest-Shamir-Adleman (RSA) or Elliptic Curve Cryptography (ECC) encryption keys, one kept private and one made public, stored in an internal key ring.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, }, }, @@ -637,6 +844,34 @@ func (r *CommPolResource) Schema(ctx context.Context, req resource.SchemaRequest }, }, }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, }, }, @@ -875,7 +1110,7 @@ func (r *CommPolResource) ImportState(ctx context.Context, req resource.ImportSt } func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *CommPolResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "commPol,commHttps,tagAnnotation,tagTag,commRsClientCertCA,commRsKeyRing,tagAnnotation"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "commPol,commHttps,tagAnnotation,tagTag,commRsClientCertCA,commRsKeyRing,tagAnnotation,tagTag,tagAnnotation,tagTag,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -935,10 +1170,20 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl CommHttpsCommPolList := make([]CommHttpsCommPolResourceModel, 0) CommRsClientCertCACommHttpsCommPol := CommRsClientCertCACommHttpsCommPolResourceModel{} CommRsClientCertCACommHttpsCommPolList := make([]CommRsClientCertCACommHttpsCommPolResourceModel, 0) + TagAnnotationCommRsClientCertCACommHttpsCommPol := TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel{} + TagAnnotationCommRsClientCertCACommHttpsCommPolList := make([]TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel, 0) + TagTagCommRsClientCertCACommHttpsCommPol := TagTagCommRsClientCertCACommHttpsCommPolResourceModel{} + TagTagCommRsClientCertCACommHttpsCommPolList := make([]TagTagCommRsClientCertCACommHttpsCommPolResourceModel, 0) CommRsKeyRingCommHttpsCommPol := CommRsKeyRingCommHttpsCommPolResourceModel{} CommRsKeyRingCommHttpsCommPolList := make([]CommRsKeyRingCommHttpsCommPolResourceModel, 0) + TagAnnotationCommRsKeyRingCommHttpsCommPol := TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel{} + TagAnnotationCommRsKeyRingCommHttpsCommPolList := make([]TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel, 0) + TagTagCommRsKeyRingCommHttpsCommPol := TagTagCommRsKeyRingCommHttpsCommPolResourceModel{} + TagTagCommRsKeyRingCommHttpsCommPolList := make([]TagTagCommRsKeyRingCommHttpsCommPolResourceModel, 0) TagAnnotationCommHttpsCommPol := TagAnnotationCommHttpsCommPolResourceModel{} TagAnnotationCommHttpsCommPolList := make([]TagAnnotationCommHttpsCommPolResourceModel, 0) + TagTagCommHttpsCommPol := TagTagCommHttpsCommPolResourceModel{} + TagTagCommHttpsCommPolList := make([]TagTagCommHttpsCommPolResourceModel, 0) TagAnnotationCommPol := TagAnnotationCommPolResourceModel{} TagAnnotationCommPolList := make([]TagAnnotationCommPolResourceModel, 0) TagTagCommPol := TagTagCommPolResourceModel{} @@ -1038,6 +1283,41 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl CommRsClientCertCACommHttpsCommPol.TDn = basetypes.NewStringValue(childAttributeValue.(string)) } } + childrenOfCommRsClientCertCACommHttpsCommPol, childrenOfCommRsClientCertCACommHttpsCommPolExist := childClassDetailsCommHttpsCommPol.(map[string]interface{})["children"] + if childrenOfCommRsClientCertCACommHttpsCommPolExist { + for _, childCommRsClientCertCACommHttpsCommPol := range childrenOfCommRsClientCertCACommHttpsCommPol.([]interface{}) { + for childClassNameCommRsClientCertCACommHttpsCommPol, childClassDetailsCommRsClientCertCACommHttpsCommPol := range childCommRsClientCertCACommHttpsCommPol.(map[string]interface{}) { + if childClassNameCommRsClientCertCACommHttpsCommPol == "tagAnnotation" { + tagAnnotationchildAttributeValue := childClassDetailsCommRsClientCertCACommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { + if childAttributeName == "key" { + TagAnnotationCommRsClientCertCACommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationCommRsClientCertCACommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagAnnotationCommRsClientCertCACommHttpsCommPolList = append(TagAnnotationCommRsClientCertCACommHttpsCommPolList, TagAnnotationCommRsClientCertCACommHttpsCommPol) + } + if childClassNameCommRsClientCertCACommHttpsCommPol == "tagTag" { + tagTagchildAttributeValue := childClassDetailsCommRsClientCertCACommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { + if childAttributeName == "key" { + TagTagCommRsClientCertCACommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagCommRsClientCertCACommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagTagCommRsClientCertCACommHttpsCommPolList = append(TagTagCommRsClientCertCACommHttpsCommPolList, TagTagCommRsClientCertCACommHttpsCommPol) + } + } + } + } + TagAnnotationCommRsClientCertCACommHttpsCommPolSet, _ := types.SetValueFrom(ctx, TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModelElementType(), TagAnnotationCommRsClientCertCACommHttpsCommPolList) + CommRsClientCertCACommHttpsCommPol.TagAnnotation = TagAnnotationCommRsClientCertCACommHttpsCommPolSet + TagTagCommRsClientCertCACommHttpsCommPolSet, _ := types.SetValueFrom(ctx, TagTagCommRsClientCertCACommHttpsCommPolResourceModelElementType(), TagTagCommRsClientCertCACommHttpsCommPolList) + CommRsClientCertCACommHttpsCommPol.TagTag = TagTagCommRsClientCertCACommHttpsCommPolSet CommRsClientCertCACommHttpsCommPolList = append(CommRsClientCertCACommHttpsCommPolList, CommRsClientCertCACommHttpsCommPol) } if childClassNameCommHttpsCommPol == "commRsKeyRing" { @@ -1050,6 +1330,41 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl CommRsKeyRingCommHttpsCommPol.TnPkiKeyRingName = basetypes.NewStringValue(childAttributeValue.(string)) } } + childrenOfCommRsKeyRingCommHttpsCommPol, childrenOfCommRsKeyRingCommHttpsCommPolExist := childClassDetailsCommHttpsCommPol.(map[string]interface{})["children"] + if childrenOfCommRsKeyRingCommHttpsCommPolExist { + for _, childCommRsKeyRingCommHttpsCommPol := range childrenOfCommRsKeyRingCommHttpsCommPol.([]interface{}) { + for childClassNameCommRsKeyRingCommHttpsCommPol, childClassDetailsCommRsKeyRingCommHttpsCommPol := range childCommRsKeyRingCommHttpsCommPol.(map[string]interface{}) { + if childClassNameCommRsKeyRingCommHttpsCommPol == "tagAnnotation" { + tagAnnotationchildAttributeValue := childClassDetailsCommRsKeyRingCommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { + if childAttributeName == "key" { + TagAnnotationCommRsKeyRingCommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationCommRsKeyRingCommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagAnnotationCommRsKeyRingCommHttpsCommPolList = append(TagAnnotationCommRsKeyRingCommHttpsCommPolList, TagAnnotationCommRsKeyRingCommHttpsCommPol) + } + if childClassNameCommRsKeyRingCommHttpsCommPol == "tagTag" { + tagTagchildAttributeValue := childClassDetailsCommRsKeyRingCommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { + if childAttributeName == "key" { + TagTagCommRsKeyRingCommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagCommRsKeyRingCommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagTagCommRsKeyRingCommHttpsCommPolList = append(TagTagCommRsKeyRingCommHttpsCommPolList, TagTagCommRsKeyRingCommHttpsCommPol) + } + } + } + } + TagAnnotationCommRsKeyRingCommHttpsCommPolSet, _ := types.SetValueFrom(ctx, TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModelElementType(), TagAnnotationCommRsKeyRingCommHttpsCommPolList) + CommRsKeyRingCommHttpsCommPol.TagAnnotation = TagAnnotationCommRsKeyRingCommHttpsCommPolSet + TagTagCommRsKeyRingCommHttpsCommPolSet, _ := types.SetValueFrom(ctx, TagTagCommRsKeyRingCommHttpsCommPolResourceModelElementType(), TagTagCommRsKeyRingCommHttpsCommPolList) + CommRsKeyRingCommHttpsCommPol.TagTag = TagTagCommRsKeyRingCommHttpsCommPolSet CommRsKeyRingCommHttpsCommPolList = append(CommRsKeyRingCommHttpsCommPolList, CommRsKeyRingCommHttpsCommPol) } if childClassNameCommHttpsCommPol == "tagAnnotation" { @@ -1064,6 +1379,18 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl } TagAnnotationCommHttpsCommPolList = append(TagAnnotationCommHttpsCommPolList, TagAnnotationCommHttpsCommPol) } + if childClassNameCommHttpsCommPol == "tagTag" { + tagTagchildAttributeValue := childClassDetailsCommHttpsCommPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { + if childAttributeName == "key" { + TagTagCommHttpsCommPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagCommHttpsCommPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagTagCommHttpsCommPolList = append(TagTagCommHttpsCommPolList, TagTagCommHttpsCommPol) + } } } } @@ -1073,6 +1400,8 @@ func getAndSetCommPolAttributes(ctx context.Context, diags *diag.Diagnostics, cl CommHttpsCommPol.CommRsKeyRing = CommRsKeyRingCommHttpsCommPolSet TagAnnotationCommHttpsCommPolSet, _ := types.SetValueFrom(ctx, TagAnnotationCommHttpsCommPolResourceModelElementType(), TagAnnotationCommHttpsCommPolList) CommHttpsCommPol.TagAnnotation = TagAnnotationCommHttpsCommPolSet + TagTagCommHttpsCommPolSet, _ := types.SetValueFrom(ctx, TagTagCommHttpsCommPolResourceModelElementType(), TagTagCommHttpsCommPolList) + CommHttpsCommPol.TagTag = TagTagCommHttpsCommPolSet CommHttpsCommPolList = append(CommHttpsCommPolList, CommHttpsCommPol) } if childClassName == "tagAnnotation" { @@ -1136,6 +1465,8 @@ func setCommPolId(ctx context.Context, data *CommPolResourceModel) { func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *CommPolResourceModel, commHttpsCommPolPlan, commHttpsCommPolState []CommHttpsCommPolResourceModel) []map[string]interface{} { childPayloads := []map[string]interface{}{} + CommRsClientCertCACommHttpsCommPolChildren := make([]map[string]interface{}, 0) + CommRsKeyRingCommHttpsCommPolChildren := make([]map[string]interface{}, 0) CommHttpsCommPolChildren := make([]map[string]interface{}, 0) if !data.CommHttps.IsNull() && !data.CommHttps.IsUnknown() { for _, commHttpsCommPol := range commHttpsCommPolPlan { @@ -1213,6 +1544,9 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti var commRsClientCertCACommHttpsCommPolPlan, commRsClientCertCACommHttpsCommPolState []CommRsClientCertCACommHttpsCommPolResourceModel commHttpsCommPol.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCACommHttpsCommPolPlan, false) + for _, commRsClientCertCACommHttpsCommPolstate := range commHttpsCommPolState { + commRsClientCertCACommHttpsCommPolstate.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCACommHttpsCommPolState, false) + } if !commHttpsCommPol.CommRsClientCertCA.IsNull() && !commHttpsCommPol.CommRsClientCertCA.IsUnknown() { for _, commRsClientCertCACommHttpsCommPol := range commRsClientCertCACommHttpsCommPolPlan { commRsClientCertCACommHttpsCommPolChildMap := NewAciObject() @@ -1224,20 +1558,95 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti if !commRsClientCertCACommHttpsCommPol.TDn.IsNull() && !commRsClientCertCACommHttpsCommPol.TDn.IsUnknown() { commRsClientCertCACommHttpsCommPolChildMap.Attributes["tDn"] = commRsClientCertCACommHttpsCommPol.TDn.ValueString() } + + var tagAnnotationCommRsClientCertCACommHttpsCommPolPlan, tagAnnotationCommRsClientCertCACommHttpsCommPolState []TagAnnotationCommRsClientCertCACommHttpsCommPolResourceModel + commRsClientCertCACommHttpsCommPol.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommRsClientCertCACommHttpsCommPolPlan, false) + for _, tagAnnotationCommRsClientCertCACommHttpsCommPolstate := range commRsClientCertCACommHttpsCommPolState { + tagAnnotationCommRsClientCertCACommHttpsCommPolstate.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommRsClientCertCACommHttpsCommPolState, false) + } + if !commRsClientCertCACommHttpsCommPol.TagAnnotation.IsNull() && !commRsClientCertCACommHttpsCommPol.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationCommRsClientCertCACommHttpsCommPol := range tagAnnotationCommRsClientCertCACommHttpsCommPolPlan { + tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap := NewAciObject() + if !tagAnnotationCommRsClientCertCACommHttpsCommPol.Key.IsNull() && !tagAnnotationCommRsClientCertCACommHttpsCommPol.Key.IsUnknown() { + tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap.Attributes["key"] = tagAnnotationCommRsClientCertCACommHttpsCommPol.Key.ValueString() + } + if !tagAnnotationCommRsClientCertCACommHttpsCommPol.Value.IsNull() && !tagAnnotationCommRsClientCertCACommHttpsCommPol.Value.IsUnknown() { + tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap.Attributes["value"] = tagAnnotationCommRsClientCertCACommHttpsCommPol.Value.ValueString() + } + CommRsClientCertCACommHttpsCommPolChildren = append(CommRsClientCertCACommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommRsClientCertCACommHttpsCommPolChildMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationCommRsClientCertCACommHttpsCommPol.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotationCommRsClientCertCACommHttpsCommPol := range tagAnnotationCommRsClientCertCACommHttpsCommPolState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotationCommRsClientCertCACommHttpsCommPol.Key { + delete = false + break + } + } + if delete { + tagAnnotationCommRsClientCertCACommHttpsCommPolChildMapForDelete := NewAciObject() + tagAnnotationCommRsClientCertCACommHttpsCommPolChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationCommRsClientCertCACommHttpsCommPolChildMapForDelete.Attributes["key"] = tagAnnotationCommRsClientCertCACommHttpsCommPol.Key.ValueString() + CommRsClientCertCACommHttpsCommPolChildren = append(CommRsClientCertCACommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommRsClientCertCACommHttpsCommPolChildMapForDelete}) + } + } + } + + var tagTagCommRsClientCertCACommHttpsCommPolPlan, tagTagCommRsClientCertCACommHttpsCommPolState []TagTagCommRsClientCertCACommHttpsCommPolResourceModel + commRsClientCertCACommHttpsCommPol.TagTag.ElementsAs(ctx, &tagTagCommRsClientCertCACommHttpsCommPolPlan, false) + for _, tagTagCommRsClientCertCACommHttpsCommPolstate := range commRsClientCertCACommHttpsCommPolState { + tagTagCommRsClientCertCACommHttpsCommPolstate.TagTag.ElementsAs(ctx, &tagTagCommRsClientCertCACommHttpsCommPolState, false) + } + if !commRsClientCertCACommHttpsCommPol.TagTag.IsNull() && !commRsClientCertCACommHttpsCommPol.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagCommRsClientCertCACommHttpsCommPol := range tagTagCommRsClientCertCACommHttpsCommPolPlan { + tagTagCommRsClientCertCACommHttpsCommPolChildMap := NewAciObject() + if !tagTagCommRsClientCertCACommHttpsCommPol.Key.IsNull() && !tagTagCommRsClientCertCACommHttpsCommPol.Key.IsUnknown() { + tagTagCommRsClientCertCACommHttpsCommPolChildMap.Attributes["key"] = tagTagCommRsClientCertCACommHttpsCommPol.Key.ValueString() + } + if !tagTagCommRsClientCertCACommHttpsCommPol.Value.IsNull() && !tagTagCommRsClientCertCACommHttpsCommPol.Value.IsUnknown() { + tagTagCommRsClientCertCACommHttpsCommPolChildMap.Attributes["value"] = tagTagCommRsClientCertCACommHttpsCommPol.Value.ValueString() + } + CommRsClientCertCACommHttpsCommPolChildren = append(CommRsClientCertCACommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommRsClientCertCACommHttpsCommPolChildMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagCommRsClientCertCACommHttpsCommPol.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTagCommRsClientCertCACommHttpsCommPol := range tagTagCommRsClientCertCACommHttpsCommPolState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTagCommRsClientCertCACommHttpsCommPol.Key { + delete = false + break + } + } + if delete { + tagTagCommRsClientCertCACommHttpsCommPolChildMapForDelete := NewAciObject() + tagTagCommRsClientCertCACommHttpsCommPolChildMapForDelete.Attributes["status"] = "deleted" + tagTagCommRsClientCertCACommHttpsCommPolChildMapForDelete.Attributes["key"] = tagTagCommRsClientCertCACommHttpsCommPol.Key.ValueString() + CommRsClientCertCACommHttpsCommPolChildren = append(CommRsClientCertCACommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommRsClientCertCACommHttpsCommPolChildMapForDelete}) + } + } + } + commRsClientCertCACommHttpsCommPolChildMap.Children = CommRsClientCertCACommHttpsCommPolChildren CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCACommHttpsCommPolChildMap}) } - for _, commHttpscommRsClientCertCAState := range commHttpsCommPolState { - commHttpscommRsClientCertCAState.CommRsClientCertCA.ElementsAs(ctx, &commRsClientCertCACommHttpsCommPolState, false) - if len(commRsClientCertCACommHttpsCommPolPlan) == 0 && len(commRsClientCertCACommHttpsCommPolState) == 1 { - commRsClientCertCACommHttpsCommPolChildMap := NewAciObject() - commRsClientCertCACommHttpsCommPolChildMap.Attributes["status"] = "deleted" - CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCACommHttpsCommPolChildMap}) - } + if len(commRsClientCertCACommHttpsCommPolPlan) == 0 && len(commRsClientCertCACommHttpsCommPolState) == 1 { + commRsClientCertCACommHttpsCommPolChildMap := NewAciObject() + commRsClientCertCACommHttpsCommPolChildMap.Attributes["status"] = "deleted" + CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"commRsClientCertCA": commRsClientCertCACommHttpsCommPolChildMap}) } } var commRsKeyRingCommHttpsCommPolPlan, commRsKeyRingCommHttpsCommPolState []CommRsKeyRingCommHttpsCommPolResourceModel commHttpsCommPol.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingCommHttpsCommPolPlan, false) + for _, commRsKeyRingCommHttpsCommPolstate := range commHttpsCommPolState { + commRsKeyRingCommHttpsCommPolstate.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingCommHttpsCommPolState, false) + } if !commHttpsCommPol.CommRsKeyRing.IsNull() && !commHttpsCommPol.CommRsKeyRing.IsUnknown() { for _, commRsKeyRingCommHttpsCommPol := range commRsKeyRingCommHttpsCommPolPlan { commRsKeyRingCommHttpsCommPolChildMap := NewAciObject() @@ -1249,22 +1658,97 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti if !commRsKeyRingCommHttpsCommPol.TnPkiKeyRingName.IsNull() && !commRsKeyRingCommHttpsCommPol.TnPkiKeyRingName.IsUnknown() { commRsKeyRingCommHttpsCommPolChildMap.Attributes["tnPkiKeyRingName"] = commRsKeyRingCommHttpsCommPol.TnPkiKeyRingName.ValueString() } + + var tagAnnotationCommRsKeyRingCommHttpsCommPolPlan, tagAnnotationCommRsKeyRingCommHttpsCommPolState []TagAnnotationCommRsKeyRingCommHttpsCommPolResourceModel + commRsKeyRingCommHttpsCommPol.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommRsKeyRingCommHttpsCommPolPlan, false) + for _, tagAnnotationCommRsKeyRingCommHttpsCommPolstate := range commRsKeyRingCommHttpsCommPolState { + tagAnnotationCommRsKeyRingCommHttpsCommPolstate.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommRsKeyRingCommHttpsCommPolState, false) + } + if !commRsKeyRingCommHttpsCommPol.TagAnnotation.IsNull() && !commRsKeyRingCommHttpsCommPol.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationCommRsKeyRingCommHttpsCommPol := range tagAnnotationCommRsKeyRingCommHttpsCommPolPlan { + tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap := NewAciObject() + if !tagAnnotationCommRsKeyRingCommHttpsCommPol.Key.IsNull() && !tagAnnotationCommRsKeyRingCommHttpsCommPol.Key.IsUnknown() { + tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap.Attributes["key"] = tagAnnotationCommRsKeyRingCommHttpsCommPol.Key.ValueString() + } + if !tagAnnotationCommRsKeyRingCommHttpsCommPol.Value.IsNull() && !tagAnnotationCommRsKeyRingCommHttpsCommPol.Value.IsUnknown() { + tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap.Attributes["value"] = tagAnnotationCommRsKeyRingCommHttpsCommPol.Value.ValueString() + } + CommRsKeyRingCommHttpsCommPolChildren = append(CommRsKeyRingCommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommRsKeyRingCommHttpsCommPolChildMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationCommRsKeyRingCommHttpsCommPol.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotationCommRsKeyRingCommHttpsCommPol := range tagAnnotationCommRsKeyRingCommHttpsCommPolState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotationCommRsKeyRingCommHttpsCommPol.Key { + delete = false + break + } + } + if delete { + tagAnnotationCommRsKeyRingCommHttpsCommPolChildMapForDelete := NewAciObject() + tagAnnotationCommRsKeyRingCommHttpsCommPolChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationCommRsKeyRingCommHttpsCommPolChildMapForDelete.Attributes["key"] = tagAnnotationCommRsKeyRingCommHttpsCommPol.Key.ValueString() + CommRsKeyRingCommHttpsCommPolChildren = append(CommRsKeyRingCommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommRsKeyRingCommHttpsCommPolChildMapForDelete}) + } + } + } + + var tagTagCommRsKeyRingCommHttpsCommPolPlan, tagTagCommRsKeyRingCommHttpsCommPolState []TagTagCommRsKeyRingCommHttpsCommPolResourceModel + commRsKeyRingCommHttpsCommPol.TagTag.ElementsAs(ctx, &tagTagCommRsKeyRingCommHttpsCommPolPlan, false) + for _, tagTagCommRsKeyRingCommHttpsCommPolstate := range commRsKeyRingCommHttpsCommPolState { + tagTagCommRsKeyRingCommHttpsCommPolstate.TagTag.ElementsAs(ctx, &tagTagCommRsKeyRingCommHttpsCommPolState, false) + } + if !commRsKeyRingCommHttpsCommPol.TagTag.IsNull() && !commRsKeyRingCommHttpsCommPol.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagCommRsKeyRingCommHttpsCommPol := range tagTagCommRsKeyRingCommHttpsCommPolPlan { + tagTagCommRsKeyRingCommHttpsCommPolChildMap := NewAciObject() + if !tagTagCommRsKeyRingCommHttpsCommPol.Key.IsNull() && !tagTagCommRsKeyRingCommHttpsCommPol.Key.IsUnknown() { + tagTagCommRsKeyRingCommHttpsCommPolChildMap.Attributes["key"] = tagTagCommRsKeyRingCommHttpsCommPol.Key.ValueString() + } + if !tagTagCommRsKeyRingCommHttpsCommPol.Value.IsNull() && !tagTagCommRsKeyRingCommHttpsCommPol.Value.IsUnknown() { + tagTagCommRsKeyRingCommHttpsCommPolChildMap.Attributes["value"] = tagTagCommRsKeyRingCommHttpsCommPol.Value.ValueString() + } + CommRsKeyRingCommHttpsCommPolChildren = append(CommRsKeyRingCommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommRsKeyRingCommHttpsCommPolChildMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagCommRsKeyRingCommHttpsCommPol.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTagCommRsKeyRingCommHttpsCommPol := range tagTagCommRsKeyRingCommHttpsCommPolState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTagCommRsKeyRingCommHttpsCommPol.Key { + delete = false + break + } + } + if delete { + tagTagCommRsKeyRingCommHttpsCommPolChildMapForDelete := NewAciObject() + tagTagCommRsKeyRingCommHttpsCommPolChildMapForDelete.Attributes["status"] = "deleted" + tagTagCommRsKeyRingCommHttpsCommPolChildMapForDelete.Attributes["key"] = tagTagCommRsKeyRingCommHttpsCommPol.Key.ValueString() + CommRsKeyRingCommHttpsCommPolChildren = append(CommRsKeyRingCommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommRsKeyRingCommHttpsCommPolChildMapForDelete}) + } + } + } + commRsKeyRingCommHttpsCommPolChildMap.Children = CommRsKeyRingCommHttpsCommPolChildren CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"commRsKeyRing": commRsKeyRingCommHttpsCommPolChildMap}) } - for _, commHttpscommRsKeyRingState := range commHttpsCommPolState { - commHttpscommRsKeyRingState.CommRsKeyRing.ElementsAs(ctx, &commRsKeyRingCommHttpsCommPolState, false) - if len(commRsKeyRingCommHttpsCommPolPlan) == 0 && len(commRsKeyRingCommHttpsCommPolState) == 1 { - diags.AddError( - "CommRsKeyRing object cannot be deleted", - "deletion of child is only possible upon deletion of the parent", - ) - return nil - } + if len(commRsKeyRingCommHttpsCommPolPlan) == 0 && len(commRsKeyRingCommHttpsCommPolState) == 1 { + diags.AddError( + "CommRsKeyRing object cannot be deleted", + "deletion of child is only possible upon deletion of the parent", + ) + return nil } } var tagAnnotationCommHttpsCommPolPlan, tagAnnotationCommHttpsCommPolState []TagAnnotationCommHttpsCommPolResourceModel commHttpsCommPol.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommHttpsCommPolPlan, false) + for _, tagAnnotationCommHttpsCommPolstate := range commHttpsCommPolState { + tagAnnotationCommHttpsCommPolstate.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommHttpsCommPolState, false) + } if !commHttpsCommPol.TagAnnotation.IsNull() && !commHttpsCommPol.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} for _, tagAnnotationCommHttpsCommPol := range tagAnnotationCommHttpsCommPolPlan { @@ -1280,23 +1764,57 @@ func getCommPolCommHttpsChildPayloads(ctx context.Context, diags *diag.Diagnosti tagAnnotationIdentifier.Key = tagAnnotationCommHttpsCommPol.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotationCommHttpsCommPolstate := range commHttpsCommPolState { - tagAnnotationCommHttpsCommPolstate.TagAnnotation.ElementsAs(ctx, &tagAnnotationCommHttpsCommPolState, false) - for _, tagAnnotationCommHttpsCommPol := range tagAnnotationCommHttpsCommPolState { - delete := true - for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { - if tagAnnotationIdentifier.Key == tagAnnotationCommHttpsCommPol.Key { - delete = false - break - } + for _, tagAnnotationCommHttpsCommPol := range tagAnnotationCommHttpsCommPolState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotationCommHttpsCommPol.Key { + delete = false + break } - if delete { - tagAnnotationCommHttpsCommPolChildMapForDelete := NewAciObject() - tagAnnotationCommHttpsCommPolChildMapForDelete.Attributes["status"] = "deleted" - tagAnnotationCommHttpsCommPolChildMapForDelete.Attributes["key"] = tagAnnotationCommHttpsCommPol.Key.ValueString() - CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommHttpsCommPolChildMapForDelete}) + } + if delete { + tagAnnotationCommHttpsCommPolChildMapForDelete := NewAciObject() + tagAnnotationCommHttpsCommPolChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationCommHttpsCommPolChildMapForDelete.Attributes["key"] = tagAnnotationCommHttpsCommPol.Key.ValueString() + CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationCommHttpsCommPolChildMapForDelete}) + } + } + } + + var tagTagCommHttpsCommPolPlan, tagTagCommHttpsCommPolState []TagTagCommHttpsCommPolResourceModel + commHttpsCommPol.TagTag.ElementsAs(ctx, &tagTagCommHttpsCommPolPlan, false) + for _, tagTagCommHttpsCommPolstate := range commHttpsCommPolState { + tagTagCommHttpsCommPolstate.TagTag.ElementsAs(ctx, &tagTagCommHttpsCommPolState, false) + } + if !commHttpsCommPol.TagTag.IsNull() && !commHttpsCommPol.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagCommHttpsCommPol := range tagTagCommHttpsCommPolPlan { + tagTagCommHttpsCommPolChildMap := NewAciObject() + if !tagTagCommHttpsCommPol.Key.IsNull() && !tagTagCommHttpsCommPol.Key.IsUnknown() { + tagTagCommHttpsCommPolChildMap.Attributes["key"] = tagTagCommHttpsCommPol.Key.ValueString() + } + if !tagTagCommHttpsCommPol.Value.IsNull() && !tagTagCommHttpsCommPol.Value.IsUnknown() { + tagTagCommHttpsCommPolChildMap.Attributes["value"] = tagTagCommHttpsCommPol.Value.ValueString() + } + CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommHttpsCommPolChildMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagCommHttpsCommPol.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTagCommHttpsCommPol := range tagTagCommHttpsCommPolState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTagCommHttpsCommPol.Key { + delete = false + break } } + if delete { + tagTagCommHttpsCommPolChildMapForDelete := NewAciObject() + tagTagCommHttpsCommPolChildMapForDelete.Attributes["status"] = "deleted" + tagTagCommHttpsCommPolChildMapForDelete.Attributes["key"] = tagTagCommHttpsCommPol.Key.ValueString() + CommHttpsCommPolChildren = append(CommHttpsCommPolChildren, map[string]interface{}{"tagTag": tagTagCommHttpsCommPolChildMapForDelete}) + } } } childMap.Children = CommHttpsCommPolChildren diff --git a/internal/provider/resource_aci_endpoint_tag_ip.go b/internal/provider/resource_aci_endpoint_tag_ip.go index d2ecf878e..2a84a8e84 100644 --- a/internal/provider/resource_aci_endpoint_tag_ip.go +++ b/internal/provider/resource_aci_endpoint_tag_ip.go @@ -13,11 +13,13 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" @@ -40,14 +42,50 @@ type FvEpIpTagResource struct { // FvEpIpTagResourceModel describes the resource data model. type FvEpIpTagResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - CtxName types.String `tfsdk:"vrf_name"` - FvEpIpTagId types.String `tfsdk:"id_attribute"` - Ip types.String `tfsdk:"ip"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + CtxName types.String `tfsdk:"vrf_name"` + FvEpIpTagId types.String `tfsdk:"id_attribute"` + Ip types.String `tfsdk:"ip"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` +} + +// TagAnnotationFvEpIpTagResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationFvEpIpTagResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationFvEpIpTagResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationFvEpIpTagResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvEpIpTagResourceModelAttributeTypes()) +} + +// TagTagFvEpIpTagResourceModel describes the resource data model for the children without relation ships. +type TagTagFvEpIpTagResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagFvEpIpTagResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagFvEpIpTagResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvEpIpTagResourceModelAttributeTypes()) } type FvEpIpTagIdentifier struct { @@ -138,6 +176,62 @@ func (r *FvEpIpTagResource) Schema(ctx context.Context, req resource.SchemaReque }, MarkdownDescription: `The name alias of the Endpoint Tag Ip object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of resource: aci_endpoint_tag_ip") @@ -167,6 +261,11 @@ func (r *FvEpIpTagResource) Configure(ctx context.Context, req resource.Configur func (r *FvEpIpTagResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_endpoint_tag_ip") + // On create retrieve information on current state prior to making any changes in order to determine child delete operations + var stateData *FvEpIpTagResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) + setFvEpIpTagId(ctx, stateData) + getAndSetFvEpIpTagAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *FvEpIpTagResourceModel @@ -181,7 +280,13 @@ func (r *FvEpIpTagResource) Create(ctx context.Context, req resource.CreateReque tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_endpoint_tag_ip with id '%s'", data.Id.ValueString())) - jsonPayload := getFvEpIpTagCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpIpTagResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagFvEpIpTagResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getFvEpIpTagCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -228,9 +333,11 @@ func (r *FvEpIpTagResource) Read(ctx context.Context, req resource.ReadRequest, func (r *FvEpIpTagResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_endpoint_tag_ip") var data *FvEpIpTagResourceModel + var stateData *FvEpIpTagResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -238,7 +345,13 @@ func (r *FvEpIpTagResource) Update(ctx context.Context, req resource.UpdateReque tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_endpoint_tag_ip with id '%s'", data.Id.ValueString())) - jsonPayload := getFvEpIpTagCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpIpTagResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagFvEpIpTagResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getFvEpIpTagCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -292,7 +405,7 @@ func (r *FvEpIpTagResource) ImportState(ctx context.Context, req resource.Import } func getAndSetFvEpIpTagAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *FvEpIpTagResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "fvEpIpTag,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -343,6 +456,47 @@ func getAndSetFvEpIpTagAttributes(ctx context.Context, diags *diag.Diagnostics, if data.NameAlias.IsUnknown() { data.NameAlias = types.StringNull() } + TagAnnotationFvEpIpTag := TagAnnotationFvEpIpTagResourceModel{} + TagAnnotationFvEpIpTagList := make([]TagAnnotationFvEpIpTagResourceModel, 0) + TagTagFvEpIpTag := TagTagFvEpIpTagResourceModel{} + TagTagFvEpIpTagList := make([]TagTagFvEpIpTagResourceModel, 0) + _, ok := classReadInfo[0].(map[string]interface{})["children"] + if ok { + children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) + for _, child := range children { + for childClassName, childClassDetails := range child.(map[string]interface{}) { + childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) + if childClassName == "tagAnnotation" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagAnnotationFvEpIpTag.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationFvEpIpTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagAnnotationFvEpIpTagList = append(TagAnnotationFvEpIpTagList, TagAnnotationFvEpIpTag) + } + if childClassName == "tagTag" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagTagFvEpIpTag.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagFvEpIpTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagTagFvEpIpTagList = append(TagTagFvEpIpTagList, TagTagFvEpIpTag) + } + } + } + } + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationFvEpIpTagList) + data.TagAnnotation = tagAnnotationSet + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagFvEpIpTagList) + data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -387,9 +541,102 @@ func setFvEpIpTagId(ctx context.Context, data *FvEpIpTagResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getFvEpIpTagCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel) *container.Container { +func getFvEpIpTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagAnnotationFvEpIpTagPlan, tagAnnotationFvEpIpTagState []TagAnnotationFvEpIpTagResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationFvEpIpTag := range tagAnnotationFvEpIpTagPlan { + childMap := NewAciObject() + if !tagAnnotationFvEpIpTag.Key.IsNull() && !tagAnnotationFvEpIpTag.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationFvEpIpTag.Key.ValueString() + } + if !tagAnnotationFvEpIpTag.Value.IsNull() && !tagAnnotationFvEpIpTag.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationFvEpIpTag.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationFvEpIpTag.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotation := range tagAnnotationFvEpIpTagState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotation.Key { + delete = false + break + } + } + if delete { + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) + } + } + } else { + data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) + } + + return childPayloads +} + +func getFvEpIpTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagTagFvEpIpTagPlan, tagTagFvEpIpTagState []TagTagFvEpIpTagResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagFvEpIpTag := range tagTagFvEpIpTagPlan { + childMap := NewAciObject() + if !tagTagFvEpIpTag.Key.IsNull() && !tagTagFvEpIpTag.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagFvEpIpTag.Key.ValueString() + } + if !tagTagFvEpIpTag.Value.IsNull() && !tagTagFvEpIpTag.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagFvEpIpTag.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagFvEpIpTag.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTag := range tagTagFvEpIpTagState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTag.Key { + delete = false + break + } + } + if delete { + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) + } + } + } else { + data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) + } + + return childPayloads +} + +func getFvEpIpTagCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvEpIpTagResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpIpTagResourceModel, tagTagPlan, tagTagState []TagTagFvEpIpTagResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} + childPayloads := []map[string]interface{}{} + + TagAnnotationchildPayloads := getFvEpIpTagTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) + if TagAnnotationchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + + TagTagchildPayloads := getFvEpIpTagTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) + if TagTagchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagTagchildPayloads...) + + payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_endpoint_tag_ip_test.go b/internal/provider/resource_aci_endpoint_tag_ip_test.go index 3df9ba093..ca8f2a19f 100644 --- a/internal/provider/resource_aci_endpoint_tag_ip_test.go +++ b/internal/provider/resource_aci_endpoint_tag_ip_test.go @@ -78,6 +78,88 @@ func TestAccResourceFvEpIpTagWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "name_alias", ""), ), }, + // Update with children + { + Config: testConfigFvEpIpTagChildrenDependencyWithFvTenant, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "ip", "10.0.0.2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "vrf_name", "test_ctx_name"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "id_attribute", "0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "name", ""), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.1.value", "value_2"), + ), + }, + // Import testing with children + { + ResourceName: "aci_endpoint_tag_ip.test", + ImportState: true, + ImportStateVerify: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "ip", "10.0.0.2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "vrf_name", "test_ctx_name"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "id_attribute", "0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "name", ""), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.1.value", "value_2"), + ), + }, + // Update with children removed from config + { + Config: testConfigFvEpIpTagChildrenRemoveFromConfigDependencyWithFvTenant, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.#", "2"), + ), + }, + // Update with children first child removed + { + Config: testConfigFvEpIpTagChildrenRemoveOneDependencyWithFvTenant, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.#", "1"), + ), + }, + // Update with all children removed + { + Config: testConfigFvEpIpTagChildrenRemoveAllDependencyWithFvTenant, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.#", "0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.#", "0"), + ), + }, }, }) } @@ -113,3 +195,68 @@ resource "aci_endpoint_tag_ip" "test" { name_alias = "" } ` +const testConfigFvEpIpTagChildrenDependencyWithFvTenant = testConfigFvTenantMin + ` +resource "aci_endpoint_tag_ip" "test" { + parent_dn = aci_tenant.test.id + ip = "10.0.0.2" + vrf_name = "test_ctx_name" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigFvEpIpTagChildrenRemoveFromConfigDependencyWithFvTenant = testConfigFvTenantMin + ` +resource "aci_endpoint_tag_ip" "test" { + parent_dn = aci_tenant.test.id + ip = "10.0.0.2" + vrf_name = "test_ctx_name" +} +` + +const testConfigFvEpIpTagChildrenRemoveOneDependencyWithFvTenant = testConfigFvTenantMin + ` +resource "aci_endpoint_tag_ip" "test" { + parent_dn = aci_tenant.test.id + ip = "10.0.0.2" + vrf_name = "test_ctx_name" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigFvEpIpTagChildrenRemoveAllDependencyWithFvTenant = testConfigFvTenantMin + ` +resource "aci_endpoint_tag_ip" "test" { + parent_dn = aci_tenant.test.id + ip = "10.0.0.2" + vrf_name = "test_ctx_name" + annotations = [] + tags = [] +} +` diff --git a/internal/provider/resource_aci_endpoint_tag_mac.go b/internal/provider/resource_aci_endpoint_tag_mac.go index 3d9f7eb4c..2306074a3 100644 --- a/internal/provider/resource_aci_endpoint_tag_mac.go +++ b/internal/provider/resource_aci_endpoint_tag_mac.go @@ -13,11 +13,13 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" @@ -40,14 +42,50 @@ type FvEpMacTagResource struct { // FvEpMacTagResourceModel describes the resource data model. type FvEpMacTagResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - BdName types.String `tfsdk:"bd_name"` - FvEpMacTagId types.String `tfsdk:"id_attribute"` - Mac types.String `tfsdk:"mac"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + BdName types.String `tfsdk:"bd_name"` + FvEpMacTagId types.String `tfsdk:"id_attribute"` + Mac types.String `tfsdk:"mac"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` +} + +// TagAnnotationFvEpMacTagResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationFvEpMacTagResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationFvEpMacTagResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationFvEpMacTagResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvEpMacTagResourceModelAttributeTypes()) +} + +// TagTagFvEpMacTagResourceModel describes the resource data model for the children without relation ships. +type TagTagFvEpMacTagResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagFvEpMacTagResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagFvEpMacTagResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvEpMacTagResourceModelAttributeTypes()) } type FvEpMacTagIdentifier struct { @@ -138,6 +176,62 @@ func (r *FvEpMacTagResource) Schema(ctx context.Context, req resource.SchemaRequ }, MarkdownDescription: `The name alias of the Endpoint Tag Mac object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of resource: aci_endpoint_tag_mac") @@ -167,6 +261,11 @@ func (r *FvEpMacTagResource) Configure(ctx context.Context, req resource.Configu func (r *FvEpMacTagResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_endpoint_tag_mac") + // On create retrieve information on current state prior to making any changes in order to determine child delete operations + var stateData *FvEpMacTagResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) + setFvEpMacTagId(ctx, stateData) + getAndSetFvEpMacTagAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *FvEpMacTagResourceModel @@ -181,7 +280,13 @@ func (r *FvEpMacTagResource) Create(ctx context.Context, req resource.CreateRequ tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_endpoint_tag_mac with id '%s'", data.Id.ValueString())) - jsonPayload := getFvEpMacTagCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpMacTagResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagFvEpMacTagResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getFvEpMacTagCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -228,9 +333,11 @@ func (r *FvEpMacTagResource) Read(ctx context.Context, req resource.ReadRequest, func (r *FvEpMacTagResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_endpoint_tag_mac") var data *FvEpMacTagResourceModel + var stateData *FvEpMacTagResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -238,7 +345,13 @@ func (r *FvEpMacTagResource) Update(ctx context.Context, req resource.UpdateRequ tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_endpoint_tag_mac with id '%s'", data.Id.ValueString())) - jsonPayload := getFvEpMacTagCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpMacTagResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagFvEpMacTagResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getFvEpMacTagCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -292,7 +405,7 @@ func (r *FvEpMacTagResource) ImportState(ctx context.Context, req resource.Impor } func getAndSetFvEpMacTagAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *FvEpMacTagResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "fvEpMacTag,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -343,6 +456,47 @@ func getAndSetFvEpMacTagAttributes(ctx context.Context, diags *diag.Diagnostics, if data.NameAlias.IsUnknown() { data.NameAlias = types.StringNull() } + TagAnnotationFvEpMacTag := TagAnnotationFvEpMacTagResourceModel{} + TagAnnotationFvEpMacTagList := make([]TagAnnotationFvEpMacTagResourceModel, 0) + TagTagFvEpMacTag := TagTagFvEpMacTagResourceModel{} + TagTagFvEpMacTagList := make([]TagTagFvEpMacTagResourceModel, 0) + _, ok := classReadInfo[0].(map[string]interface{})["children"] + if ok { + children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) + for _, child := range children { + for childClassName, childClassDetails := range child.(map[string]interface{}) { + childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) + if childClassName == "tagAnnotation" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagAnnotationFvEpMacTag.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationFvEpMacTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagAnnotationFvEpMacTagList = append(TagAnnotationFvEpMacTagList, TagAnnotationFvEpMacTag) + } + if childClassName == "tagTag" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagTagFvEpMacTag.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagFvEpMacTag.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagTagFvEpMacTagList = append(TagTagFvEpMacTagList, TagTagFvEpMacTag) + } + } + } + } + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationFvEpMacTagList) + data.TagAnnotation = tagAnnotationSet + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagFvEpMacTagList) + data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -387,9 +541,102 @@ func setFvEpMacTagId(ctx context.Context, data *FvEpMacTagResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getFvEpMacTagCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel) *container.Container { +func getFvEpMacTagTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagAnnotationFvEpMacTagPlan, tagAnnotationFvEpMacTagState []TagAnnotationFvEpMacTagResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationFvEpMacTag := range tagAnnotationFvEpMacTagPlan { + childMap := NewAciObject() + if !tagAnnotationFvEpMacTag.Key.IsNull() && !tagAnnotationFvEpMacTag.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationFvEpMacTag.Key.ValueString() + } + if !tagAnnotationFvEpMacTag.Value.IsNull() && !tagAnnotationFvEpMacTag.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationFvEpMacTag.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationFvEpMacTag.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotation := range tagAnnotationFvEpMacTagState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotation.Key { + delete = false + break + } + } + if delete { + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) + } + } + } else { + data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) + } + + return childPayloads +} + +func getFvEpMacTagTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagTagFvEpMacTagPlan, tagTagFvEpMacTagState []TagTagFvEpMacTagResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagFvEpMacTag := range tagTagFvEpMacTagPlan { + childMap := NewAciObject() + if !tagTagFvEpMacTag.Key.IsNull() && !tagTagFvEpMacTag.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagFvEpMacTag.Key.ValueString() + } + if !tagTagFvEpMacTag.Value.IsNull() && !tagTagFvEpMacTag.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagFvEpMacTag.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagFvEpMacTag.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTag := range tagTagFvEpMacTagState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTag.Key { + delete = false + break + } + } + if delete { + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) + } + } + } else { + data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) + } + + return childPayloads +} + +func getFvEpMacTagCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvEpMacTagResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvEpMacTagResourceModel, tagTagPlan, tagTagState []TagTagFvEpMacTagResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} + childPayloads := []map[string]interface{}{} + + TagAnnotationchildPayloads := getFvEpMacTagTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) + if TagAnnotationchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + + TagTagchildPayloads := getFvEpMacTagTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) + if TagTagchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagTagchildPayloads...) + + payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_endpoint_tag_mac_test.go b/internal/provider/resource_aci_endpoint_tag_mac_test.go index 71463e256..5dd5781ef 100644 --- a/internal/provider/resource_aci_endpoint_tag_mac_test.go +++ b/internal/provider/resource_aci_endpoint_tag_mac_test.go @@ -78,6 +78,88 @@ func TestAccResourceFvEpMacTagWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "name_alias", ""), ), }, + // Update with children + { + Config: testConfigFvEpMacTagChildrenDependencyWithFvTenant, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "bd_name", "test_bd_name"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "mac", "00:00:00:00:00:01"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "id_attribute", "0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "name", ""), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.1.value", "value_2"), + ), + }, + // Import testing with children + { + ResourceName: "aci_endpoint_tag_mac.test", + ImportState: true, + ImportStateVerify: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "bd_name", "test_bd_name"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "mac", "00:00:00:00:00:01"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "id_attribute", "0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "name", ""), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.1.value", "value_2"), + ), + }, + // Update with children removed from config + { + Config: testConfigFvEpMacTagChildrenRemoveFromConfigDependencyWithFvTenant, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.#", "2"), + ), + }, + // Update with children first child removed + { + Config: testConfigFvEpMacTagChildrenRemoveOneDependencyWithFvTenant, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.#", "1"), + ), + }, + // Update with all children removed + { + Config: testConfigFvEpMacTagChildrenRemoveAllDependencyWithFvTenant, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.#", "0"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.#", "0"), + ), + }, }, }) } @@ -113,3 +195,68 @@ resource "aci_endpoint_tag_mac" "test" { name_alias = "" } ` +const testConfigFvEpMacTagChildrenDependencyWithFvTenant = testConfigFvTenantMin + ` +resource "aci_endpoint_tag_mac" "test" { + parent_dn = aci_tenant.test.id + bd_name = "test_bd_name" + mac = "00:00:00:00:00:01" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigFvEpMacTagChildrenRemoveFromConfigDependencyWithFvTenant = testConfigFvTenantMin + ` +resource "aci_endpoint_tag_mac" "test" { + parent_dn = aci_tenant.test.id + bd_name = "test_bd_name" + mac = "00:00:00:00:00:01" +} +` + +const testConfigFvEpMacTagChildrenRemoveOneDependencyWithFvTenant = testConfigFvTenantMin + ` +resource "aci_endpoint_tag_mac" "test" { + parent_dn = aci_tenant.test.id + bd_name = "test_bd_name" + mac = "00:00:00:00:00:01" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigFvEpMacTagChildrenRemoveAllDependencyWithFvTenant = testConfigFvTenantMin + ` +resource "aci_endpoint_tag_mac" "test" { + parent_dn = aci_tenant.test.id + bd_name = "test_bd_name" + mac = "00:00:00:00:00:01" + annotations = [] + tags = [] +} +` 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 ac3b57b21..fe55b0095 100644 --- a/internal/provider/resource_aci_external_management_network_instance_profile.go +++ b/internal/provider/resource_aci_external_management_network_instance_profile.go @@ -51,6 +51,8 @@ type MgmtInstPResourceModel struct { NameAlias types.String `tfsdk:"name_alias"` Prio types.String `tfsdk:"priority"` MgmtRsOoBCons types.Set `tfsdk:"relation_to_consumed_out_of_band_contracts"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` } // MgmtRsOoBConsMgmtInstPResourceModel describes the resource data model for the children without relation ships. @@ -58,6 +60,8 @@ type MgmtRsOoBConsMgmtInstPResourceModel struct { Annotation types.String `tfsdk:"annotation"` Prio types.String `tfsdk:"priority"` TnVzOOBBrCPName types.String `tfsdk:"out_of_band_contract_name"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` } func MgmtRsOoBConsMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { @@ -65,6 +69,8 @@ func MgmtRsOoBConsMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { "annotation": types.StringType, "priority": types.StringType, "out_of_band_contract_name": types.StringType, + "annotations": types.SetType{ElemType: TagAnnotationMgmtRsOoBConsMgmtInstPResourceModelElementType()}, + "tags": types.SetType{ElemType: TagTagMgmtRsOoBConsMgmtInstPResourceModelElementType()}, } } @@ -72,6 +78,74 @@ func MgmtRsOoBConsMgmtInstPResourceModelElementType() attr.TypeWithAttributeType return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, MgmtRsOoBConsMgmtInstPResourceModelAttributeTypes()) } +// TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationMgmtRsOoBConsMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationMgmtRsOoBConsMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtRsOoBConsMgmtInstPResourceModelAttributeTypes()) +} + +// TagTagMgmtRsOoBConsMgmtInstPResourceModel describes the resource data model for the children without relation ships. +type TagTagMgmtRsOoBConsMgmtInstPResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagMgmtRsOoBConsMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagMgmtRsOoBConsMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtRsOoBConsMgmtInstPResourceModelAttributeTypes()) +} + +// TagAnnotationMgmtInstPResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationMgmtInstPResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtInstPResourceModelAttributeTypes()) +} + +// TagTagMgmtInstPResourceModel describes the resource data model for the children without relation ships. +type TagTagMgmtInstPResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagMgmtInstPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagMgmtInstPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtInstPResourceModelAttributeTypes()) +} + type MgmtInstPIdentifier struct { Name types.String } @@ -183,6 +257,118 @@ func (r *MgmtInstPResource) Schema(ctx context.Context, req resource.SchemaReque }, MarkdownDescription: `The name of the Out Of Band Contract object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + }, + }, + }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, }, }, }, @@ -237,7 +423,13 @@ func (r *MgmtInstPResource) Create(ctx context.Context, req resource.CreateReque var mgmtRsOoBConsPlan, mgmtRsOoBConsState []MgmtRsOoBConsMgmtInstPResourceModel data.MgmtRsOoBCons.ElementsAs(ctx, &mgmtRsOoBConsPlan, false) stateData.MgmtRsOoBCons.ElementsAs(ctx, &mgmtRsOoBConsState, false) - jsonPayload := getMgmtInstPCreateJsonPayload(ctx, &resp.Diagnostics, data, mgmtRsOoBConsPlan, mgmtRsOoBConsState) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtInstPResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagMgmtInstPResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getMgmtInstPCreateJsonPayload(ctx, &resp.Diagnostics, data, mgmtRsOoBConsPlan, mgmtRsOoBConsState, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -299,7 +491,13 @@ func (r *MgmtInstPResource) Update(ctx context.Context, req resource.UpdateReque var mgmtRsOoBConsPlan, mgmtRsOoBConsState []MgmtRsOoBConsMgmtInstPResourceModel data.MgmtRsOoBCons.ElementsAs(ctx, &mgmtRsOoBConsPlan, false) stateData.MgmtRsOoBCons.ElementsAs(ctx, &mgmtRsOoBConsState, false) - jsonPayload := getMgmtInstPCreateJsonPayload(ctx, &resp.Diagnostics, data, mgmtRsOoBConsPlan, mgmtRsOoBConsState) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtInstPResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagMgmtInstPResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getMgmtInstPCreateJsonPayload(ctx, &resp.Diagnostics, data, mgmtRsOoBConsPlan, mgmtRsOoBConsState, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -353,7 +551,7 @@ func (r *MgmtInstPResource) ImportState(ctx context.Context, req resource.Import } func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *MgmtInstPResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtInstP,mgmtRsOoBCons"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtInstP,mgmtRsOoBCons,tagAnnotation,tagTag,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -399,6 +597,14 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, } MgmtRsOoBConsMgmtInstP := MgmtRsOoBConsMgmtInstPResourceModel{} MgmtRsOoBConsMgmtInstPList := make([]MgmtRsOoBConsMgmtInstPResourceModel, 0) + TagAnnotationMgmtRsOoBConsMgmtInstP := TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel{} + TagAnnotationMgmtRsOoBConsMgmtInstPList := make([]TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel, 0) + TagTagMgmtRsOoBConsMgmtInstP := TagTagMgmtRsOoBConsMgmtInstPResourceModel{} + TagTagMgmtRsOoBConsMgmtInstPList := make([]TagTagMgmtRsOoBConsMgmtInstPResourceModel, 0) + TagAnnotationMgmtInstP := TagAnnotationMgmtInstPResourceModel{} + TagAnnotationMgmtInstPList := make([]TagAnnotationMgmtInstPResourceModel, 0) + TagTagMgmtInstP := TagTagMgmtInstPResourceModel{} + TagTagMgmtInstPList := make([]TagTagMgmtInstPResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) @@ -418,13 +624,76 @@ func getAndSetMgmtInstPAttributes(ctx context.Context, diags *diag.Diagnostics, } } + childrenOfMgmtRsOoBConsMgmtInstP, childrenOfMgmtRsOoBConsMgmtInstPExist := childClassDetails.(map[string]interface{})["children"] + if childrenOfMgmtRsOoBConsMgmtInstPExist { + for _, childMgmtRsOoBConsMgmtInstP := range childrenOfMgmtRsOoBConsMgmtInstP.([]interface{}) { + for childClassNameMgmtRsOoBConsMgmtInstP, childClassDetailsMgmtRsOoBConsMgmtInstP := range childMgmtRsOoBConsMgmtInstP.(map[string]interface{}) { + if childClassNameMgmtRsOoBConsMgmtInstP == "tagAnnotation" { + tagAnnotationchildAttributeValue := childClassDetailsMgmtRsOoBConsMgmtInstP.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { + if childAttributeName == "key" { + TagAnnotationMgmtRsOoBConsMgmtInstP.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationMgmtRsOoBConsMgmtInstP.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagAnnotationMgmtRsOoBConsMgmtInstPList = append(TagAnnotationMgmtRsOoBConsMgmtInstPList, TagAnnotationMgmtRsOoBConsMgmtInstP) + } + if childClassNameMgmtRsOoBConsMgmtInstP == "tagTag" { + tagTagchildAttributeValue := childClassDetailsMgmtRsOoBConsMgmtInstP.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { + if childAttributeName == "key" { + TagTagMgmtRsOoBConsMgmtInstP.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagMgmtRsOoBConsMgmtInstP.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagTagMgmtRsOoBConsMgmtInstPList = append(TagTagMgmtRsOoBConsMgmtInstPList, TagTagMgmtRsOoBConsMgmtInstP) + } + } + } + } + TagAnnotationMgmtRsOoBConsMgmtInstPSet, _ := types.SetValueFrom(ctx, TagAnnotationMgmtRsOoBConsMgmtInstPResourceModelElementType(), TagAnnotationMgmtRsOoBConsMgmtInstPList) + MgmtRsOoBConsMgmtInstP.TagAnnotation = TagAnnotationMgmtRsOoBConsMgmtInstPSet + TagTagMgmtRsOoBConsMgmtInstPSet, _ := types.SetValueFrom(ctx, TagTagMgmtRsOoBConsMgmtInstPResourceModelElementType(), TagTagMgmtRsOoBConsMgmtInstPList) + MgmtRsOoBConsMgmtInstP.TagTag = TagTagMgmtRsOoBConsMgmtInstPSet MgmtRsOoBConsMgmtInstPList = append(MgmtRsOoBConsMgmtInstPList, MgmtRsOoBConsMgmtInstP) } + if childClassName == "tagAnnotation" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagAnnotationMgmtInstP.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationMgmtInstP.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagAnnotationMgmtInstPList = append(TagAnnotationMgmtInstPList, TagAnnotationMgmtInstP) + } + if childClassName == "tagTag" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagTagMgmtInstP.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagMgmtInstP.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagTagMgmtInstPList = append(TagTagMgmtInstPList, TagTagMgmtInstP) + } } } } mgmtRsOoBConsSet, _ := types.SetValueFrom(ctx, data.MgmtRsOoBCons.ElementType(ctx), MgmtRsOoBConsMgmtInstPList) data.MgmtRsOoBCons = mgmtRsOoBConsSet + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationMgmtInstPList) + data.TagAnnotation = tagAnnotationSet + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagMgmtInstPList) + data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -453,6 +722,7 @@ func setMgmtInstPId(ctx context.Context, data *MgmtInstPResourceModel) { func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, mgmtRsOoBConsMgmtInstPPlan, mgmtRsOoBConsMgmtInstPState []MgmtRsOoBConsMgmtInstPResourceModel) []map[string]interface{} { childPayloads := []map[string]interface{}{} + MgmtRsOoBConsMgmtInstPChildren := make([]map[string]interface{}, 0) if !data.MgmtRsOoBCons.IsNull() && !data.MgmtRsOoBCons.IsUnknown() { mgmtRsOoBConsIdentifiers := []MgmtRsOoBConsIdentifier{} for _, mgmtRsOoBConsMgmtInstP := range mgmtRsOoBConsMgmtInstPPlan { @@ -468,6 +738,81 @@ func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Dia if !mgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName.IsNull() && !mgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName.IsUnknown() { childMap.Attributes["tnVzOOBBrCPName"] = mgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName.ValueString() } + + var tagAnnotationMgmtRsOoBConsMgmtInstPPlan, tagAnnotationMgmtRsOoBConsMgmtInstPState []TagAnnotationMgmtRsOoBConsMgmtInstPResourceModel + mgmtRsOoBConsMgmtInstP.TagAnnotation.ElementsAs(ctx, &tagAnnotationMgmtRsOoBConsMgmtInstPPlan, false) + for _, tagAnnotationMgmtRsOoBConsMgmtInstPstate := range mgmtRsOoBConsMgmtInstPState { + tagAnnotationMgmtRsOoBConsMgmtInstPstate.TagAnnotation.ElementsAs(ctx, &tagAnnotationMgmtRsOoBConsMgmtInstPState, false) + } + if !mgmtRsOoBConsMgmtInstP.TagAnnotation.IsNull() && !mgmtRsOoBConsMgmtInstP.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationMgmtRsOoBConsMgmtInstP := range tagAnnotationMgmtRsOoBConsMgmtInstPPlan { + tagAnnotationMgmtRsOoBConsMgmtInstPChildMap := NewAciObject() + if !tagAnnotationMgmtRsOoBConsMgmtInstP.Key.IsNull() && !tagAnnotationMgmtRsOoBConsMgmtInstP.Key.IsUnknown() { + tagAnnotationMgmtRsOoBConsMgmtInstPChildMap.Attributes["key"] = tagAnnotationMgmtRsOoBConsMgmtInstP.Key.ValueString() + } + if !tagAnnotationMgmtRsOoBConsMgmtInstP.Value.IsNull() && !tagAnnotationMgmtRsOoBConsMgmtInstP.Value.IsUnknown() { + tagAnnotationMgmtRsOoBConsMgmtInstPChildMap.Attributes["value"] = tagAnnotationMgmtRsOoBConsMgmtInstP.Value.ValueString() + } + MgmtRsOoBConsMgmtInstPChildren = append(MgmtRsOoBConsMgmtInstPChildren, map[string]interface{}{"tagAnnotation": tagAnnotationMgmtRsOoBConsMgmtInstPChildMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationMgmtRsOoBConsMgmtInstP.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotationMgmtRsOoBConsMgmtInstP := range tagAnnotationMgmtRsOoBConsMgmtInstPState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotationMgmtRsOoBConsMgmtInstP.Key { + delete = false + break + } + } + if delete { + tagAnnotationMgmtRsOoBConsMgmtInstPChildMapForDelete := NewAciObject() + tagAnnotationMgmtRsOoBConsMgmtInstPChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationMgmtRsOoBConsMgmtInstPChildMapForDelete.Attributes["key"] = tagAnnotationMgmtRsOoBConsMgmtInstP.Key.ValueString() + MgmtRsOoBConsMgmtInstPChildren = append(MgmtRsOoBConsMgmtInstPChildren, map[string]interface{}{"tagAnnotation": tagAnnotationMgmtRsOoBConsMgmtInstPChildMapForDelete}) + } + } + } + + var tagTagMgmtRsOoBConsMgmtInstPPlan, tagTagMgmtRsOoBConsMgmtInstPState []TagTagMgmtRsOoBConsMgmtInstPResourceModel + mgmtRsOoBConsMgmtInstP.TagTag.ElementsAs(ctx, &tagTagMgmtRsOoBConsMgmtInstPPlan, false) + for _, tagTagMgmtRsOoBConsMgmtInstPstate := range mgmtRsOoBConsMgmtInstPState { + tagTagMgmtRsOoBConsMgmtInstPstate.TagTag.ElementsAs(ctx, &tagTagMgmtRsOoBConsMgmtInstPState, false) + } + if !mgmtRsOoBConsMgmtInstP.TagTag.IsNull() && !mgmtRsOoBConsMgmtInstP.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagMgmtRsOoBConsMgmtInstP := range tagTagMgmtRsOoBConsMgmtInstPPlan { + tagTagMgmtRsOoBConsMgmtInstPChildMap := NewAciObject() + if !tagTagMgmtRsOoBConsMgmtInstP.Key.IsNull() && !tagTagMgmtRsOoBConsMgmtInstP.Key.IsUnknown() { + tagTagMgmtRsOoBConsMgmtInstPChildMap.Attributes["key"] = tagTagMgmtRsOoBConsMgmtInstP.Key.ValueString() + } + if !tagTagMgmtRsOoBConsMgmtInstP.Value.IsNull() && !tagTagMgmtRsOoBConsMgmtInstP.Value.IsUnknown() { + tagTagMgmtRsOoBConsMgmtInstPChildMap.Attributes["value"] = tagTagMgmtRsOoBConsMgmtInstP.Value.ValueString() + } + MgmtRsOoBConsMgmtInstPChildren = append(MgmtRsOoBConsMgmtInstPChildren, map[string]interface{}{"tagTag": tagTagMgmtRsOoBConsMgmtInstPChildMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagMgmtRsOoBConsMgmtInstP.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTagMgmtRsOoBConsMgmtInstP := range tagTagMgmtRsOoBConsMgmtInstPState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTagMgmtRsOoBConsMgmtInstP.Key { + delete = false + break + } + } + if delete { + tagTagMgmtRsOoBConsMgmtInstPChildMapForDelete := NewAciObject() + tagTagMgmtRsOoBConsMgmtInstPChildMapForDelete.Attributes["status"] = "deleted" + tagTagMgmtRsOoBConsMgmtInstPChildMapForDelete.Attributes["key"] = tagTagMgmtRsOoBConsMgmtInstP.Key.ValueString() + MgmtRsOoBConsMgmtInstPChildren = append(MgmtRsOoBConsMgmtInstPChildren, map[string]interface{}{"tagTag": tagTagMgmtRsOoBConsMgmtInstPChildMapForDelete}) + } + } + } + childMap.Children = MgmtRsOoBConsMgmtInstPChildren childPayloads = append(childPayloads, map[string]interface{}{"mgmtRsOoBCons": childMap}) mgmtRsOoBConsIdentifier := MgmtRsOoBConsIdentifier{} mgmtRsOoBConsIdentifier.TnVzOOBBrCPName = mgmtRsOoBConsMgmtInstP.TnVzOOBBrCPName @@ -495,7 +840,85 @@ func getMgmtInstPMgmtRsOoBConsChildPayloads(ctx context.Context, diags *diag.Dia return childPayloads } -func getMgmtInstPCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, mgmtRsOoBConsPlan, mgmtRsOoBConsState []MgmtRsOoBConsMgmtInstPResourceModel) *container.Container { +func getMgmtInstPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagAnnotationMgmtInstPPlan, tagAnnotationMgmtInstPState []TagAnnotationMgmtInstPResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationMgmtInstP := range tagAnnotationMgmtInstPPlan { + childMap := NewAciObject() + if !tagAnnotationMgmtInstP.Key.IsNull() && !tagAnnotationMgmtInstP.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationMgmtInstP.Key.ValueString() + } + if !tagAnnotationMgmtInstP.Value.IsNull() && !tagAnnotationMgmtInstP.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationMgmtInstP.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationMgmtInstP.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotation := range tagAnnotationMgmtInstPState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotation.Key { + delete = false + break + } + } + if delete { + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) + } + } + } else { + data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) + } + + return childPayloads +} + +func getMgmtInstPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, tagTagMgmtInstPPlan, tagTagMgmtInstPState []TagTagMgmtInstPResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagMgmtInstP := range tagTagMgmtInstPPlan { + childMap := NewAciObject() + if !tagTagMgmtInstP.Key.IsNull() && !tagTagMgmtInstP.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagMgmtInstP.Key.ValueString() + } + if !tagTagMgmtInstP.Value.IsNull() && !tagTagMgmtInstP.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagMgmtInstP.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagMgmtInstP.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTag := range tagTagMgmtInstPState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTag.Key { + delete = false + break + } + } + if delete { + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) + } + } + } else { + data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) + } + + return childPayloads +} + +func getMgmtInstPCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *MgmtInstPResourceModel, mgmtRsOoBConsPlan, mgmtRsOoBConsState []MgmtRsOoBConsMgmtInstPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtInstPResourceModel, tagTagPlan, tagTagState []TagTagMgmtInstPResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} childPayloads := []map[string]interface{}{} @@ -506,6 +929,18 @@ func getMgmtInstPCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, } childPayloads = append(childPayloads, MgmtRsOoBConschildPayloads...) + TagAnnotationchildPayloads := getMgmtInstPTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) + if TagAnnotationchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + + TagTagchildPayloads := getMgmtInstPTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) + if TagTagchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagTagchildPayloads...) + payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() diff --git a/internal/provider/resource_aci_external_management_network_instance_profile_test.go b/internal/provider/resource_aci_external_management_network_instance_profile_test.go index d69a86416..32808d79d 100644 --- a/internal/provider/resource_aci_external_management_network_instance_profile_test.go +++ b/internal/provider/resource_aci_external_management_network_instance_profile_test.go @@ -81,6 +81,11 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "description", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "name_alias", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "priority", "unspecified"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.#", "2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level1"), @@ -88,6 +93,11 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.priority", "level2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "2"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.#", "2"), ), }, // Update with children removed from config @@ -98,6 +108,11 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "description", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "name_alias", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "priority", "unspecified"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.#", "2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level1"), @@ -105,6 +120,11 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.priority", "level2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "2"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.#", "2"), ), }, // Update with children first child removed @@ -115,10 +135,16 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "description", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "name_alias", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "priority", "unspecified"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.#", "1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.annotation", "annotation_2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "1"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.#", "1"), ), }, // Update with all children removed @@ -129,7 +155,9 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "description", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "name_alias", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "priority", "unspecified"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.#", "0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "0"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.#", "0"), ), }, }, @@ -164,6 +192,16 @@ resource "aci_external_management_network_instance_profile" "test" { const testConfigMgmtInstPChildren = ` resource "aci_external_management_network_instance_profile" "test" { name = "test_name" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] relation_to_consumed_out_of_band_contracts = [ { annotation = "annotation_1" @@ -176,6 +214,16 @@ resource "aci_external_management_network_instance_profile" "test" { priority = "level2" }, ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] } ` @@ -188,6 +236,12 @@ resource "aci_external_management_network_instance_profile" "test" { const testConfigMgmtInstPChildrenRemoveOne = ` resource "aci_external_management_network_instance_profile" "test" { name = "test_name" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] relation_to_consumed_out_of_band_contracts = [ { annotation = "annotation_2" @@ -195,12 +249,20 @@ resource "aci_external_management_network_instance_profile" "test" { priority = "level2" }, ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] } ` const testConfigMgmtInstPChildrenRemoveAll = ` resource "aci_external_management_network_instance_profile" "test" { name = "test_name" + annotations = [] relation_to_consumed_out_of_band_contracts = [] + tags = [] } ` diff --git a/internal/provider/resource_aci_external_management_network_subnet.go b/internal/provider/resource_aci_external_management_network_subnet.go index 2b5d1e6b3..264239c49 100644 --- a/internal/provider/resource_aci_external_management_network_subnet.go +++ b/internal/provider/resource_aci_external_management_network_subnet.go @@ -13,11 +13,13 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" @@ -40,13 +42,49 @@ type MgmtSubnetResource struct { // MgmtSubnetResourceModel describes the resource data model. type MgmtSubnetResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Ip types.String `tfsdk:"ip"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Ip types.String `tfsdk:"ip"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` +} + +// TagAnnotationMgmtSubnetResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationMgmtSubnetResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationMgmtSubnetResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationMgmtSubnetResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtSubnetResourceModelAttributeTypes()) +} + +// TagTagMgmtSubnetResourceModel describes the resource data model for the children without relation ships. +type TagTagMgmtSubnetResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagMgmtSubnetResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagMgmtSubnetResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtSubnetResourceModelAttributeTypes()) } type MgmtSubnetIdentifier struct { @@ -127,6 +165,62 @@ func (r *MgmtSubnetResource) Schema(ctx context.Context, req resource.SchemaRequ }, MarkdownDescription: `The name alias of the External Management Network Subnet object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of resource: aci_external_management_network_subnet") @@ -156,6 +250,11 @@ func (r *MgmtSubnetResource) Configure(ctx context.Context, req resource.Configu func (r *MgmtSubnetResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_external_management_network_subnet") + // On create retrieve information on current state prior to making any changes in order to determine child delete operations + var stateData *MgmtSubnetResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) + setMgmtSubnetId(ctx, stateData) + getAndSetMgmtSubnetAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *MgmtSubnetResourceModel @@ -170,7 +269,13 @@ func (r *MgmtSubnetResource) Create(ctx context.Context, req resource.CreateRequ tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_external_management_network_subnet with id '%s'", data.Id.ValueString())) - jsonPayload := getMgmtSubnetCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtSubnetResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagMgmtSubnetResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getMgmtSubnetCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -217,9 +322,11 @@ func (r *MgmtSubnetResource) Read(ctx context.Context, req resource.ReadRequest, func (r *MgmtSubnetResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_external_management_network_subnet") var data *MgmtSubnetResourceModel + var stateData *MgmtSubnetResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -227,7 +334,13 @@ func (r *MgmtSubnetResource) Update(ctx context.Context, req resource.UpdateRequ tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_external_management_network_subnet with id '%s'", data.Id.ValueString())) - jsonPayload := getMgmtSubnetCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtSubnetResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagMgmtSubnetResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getMgmtSubnetCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -281,7 +394,7 @@ func (r *MgmtSubnetResource) ImportState(ctx context.Context, req resource.Impor } func getAndSetMgmtSubnetAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *MgmtSubnetResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtSubnet,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -326,6 +439,47 @@ func getAndSetMgmtSubnetAttributes(ctx context.Context, diags *diag.Diagnostics, if data.NameAlias.IsUnknown() { data.NameAlias = types.StringNull() } + TagAnnotationMgmtSubnet := TagAnnotationMgmtSubnetResourceModel{} + TagAnnotationMgmtSubnetList := make([]TagAnnotationMgmtSubnetResourceModel, 0) + TagTagMgmtSubnet := TagTagMgmtSubnetResourceModel{} + TagTagMgmtSubnetList := make([]TagTagMgmtSubnetResourceModel, 0) + _, ok := classReadInfo[0].(map[string]interface{})["children"] + if ok { + children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) + for _, child := range children { + for childClassName, childClassDetails := range child.(map[string]interface{}) { + childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) + if childClassName == "tagAnnotation" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagAnnotationMgmtSubnet.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationMgmtSubnet.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagAnnotationMgmtSubnetList = append(TagAnnotationMgmtSubnetList, TagAnnotationMgmtSubnet) + } + if childClassName == "tagTag" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagTagMgmtSubnet.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagMgmtSubnet.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagTagMgmtSubnetList = append(TagTagMgmtSubnetList, TagTagMgmtSubnet) + } + } + } + } + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationMgmtSubnetList) + data.TagAnnotation = tagAnnotationSet + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagMgmtSubnetList) + data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -368,9 +522,102 @@ func setMgmtSubnetId(ctx context.Context, data *MgmtSubnetResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getMgmtSubnetCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel) *container.Container { +func getMgmtSubnetTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagAnnotationMgmtSubnetPlan, tagAnnotationMgmtSubnetState []TagAnnotationMgmtSubnetResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationMgmtSubnet := range tagAnnotationMgmtSubnetPlan { + childMap := NewAciObject() + if !tagAnnotationMgmtSubnet.Key.IsNull() && !tagAnnotationMgmtSubnet.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationMgmtSubnet.Key.ValueString() + } + if !tagAnnotationMgmtSubnet.Value.IsNull() && !tagAnnotationMgmtSubnet.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationMgmtSubnet.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationMgmtSubnet.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotation := range tagAnnotationMgmtSubnetState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotation.Key { + delete = false + break + } + } + if delete { + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) + } + } + } else { + data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) + } + + return childPayloads +} + +func getMgmtSubnetTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagTagMgmtSubnetPlan, tagTagMgmtSubnetState []TagTagMgmtSubnetResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagMgmtSubnet := range tagTagMgmtSubnetPlan { + childMap := NewAciObject() + if !tagTagMgmtSubnet.Key.IsNull() && !tagTagMgmtSubnet.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagMgmtSubnet.Key.ValueString() + } + if !tagTagMgmtSubnet.Value.IsNull() && !tagTagMgmtSubnet.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagMgmtSubnet.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagMgmtSubnet.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTag := range tagTagMgmtSubnetState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTag.Key { + delete = false + break + } + } + if delete { + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) + } + } + } else { + data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) + } + + return childPayloads +} + +func getMgmtSubnetCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *MgmtSubnetResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtSubnetResourceModel, tagTagPlan, tagTagState []TagTagMgmtSubnetResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} + childPayloads := []map[string]interface{}{} + + TagAnnotationchildPayloads := getMgmtSubnetTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) + if TagAnnotationchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + + TagTagchildPayloads := getMgmtSubnetTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) + if TagTagchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagTagchildPayloads...) + + payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_external_management_network_subnet_test.go b/internal/provider/resource_aci_external_management_network_subnet_test.go index 369d3007f..6bdd85a8f 100644 --- a/internal/provider/resource_aci_external_management_network_subnet_test.go +++ b/internal/provider/resource_aci_external_management_network_subnet_test.go @@ -73,6 +73,86 @@ func TestAccResourceMgmtSubnetWithMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "name_alias", ""), ), }, + // Update with children + { + Config: testConfigMgmtSubnetChildrenDependencyWithMgmtInstP, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "ip", "1.1.1.0/24"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "description", ""), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "name", ""), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.1.value", "value_2"), + ), + }, + // Import testing with children + { + ResourceName: "aci_external_management_network_subnet.test", + ImportState: true, + ImportStateVerify: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "ip", "1.1.1.0/24"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "description", ""), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "name", ""), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.1.value", "value_2"), + ), + }, + // Update with children removed from config + { + Config: testConfigMgmtSubnetChildrenRemoveFromConfigDependencyWithMgmtInstP, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.#", "2"), + ), + }, + // Update with children first child removed + { + Config: testConfigMgmtSubnetChildrenRemoveOneDependencyWithMgmtInstP, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.#", "1"), + ), + }, + // Update with all children removed + { + Config: testConfigMgmtSubnetChildrenRemoveAllDependencyWithMgmtInstP, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.#", "0"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.#", "0"), + ), + }, }, }) } @@ -105,3 +185,64 @@ resource "aci_external_management_network_subnet" "test" { name_alias = "" } ` +const testConfigMgmtSubnetChildrenDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` +resource "aci_external_management_network_subnet" "test" { + parent_dn = aci_external_management_network_instance_profile.test.id + ip = "1.1.1.0/24" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigMgmtSubnetChildrenRemoveFromConfigDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` +resource "aci_external_management_network_subnet" "test" { + parent_dn = aci_external_management_network_instance_profile.test.id + ip = "1.1.1.0/24" +} +` + +const testConfigMgmtSubnetChildrenRemoveOneDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` +resource "aci_external_management_network_subnet" "test" { + parent_dn = aci_external_management_network_instance_profile.test.id + ip = "1.1.1.0/24" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigMgmtSubnetChildrenRemoveAllDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` +resource "aci_external_management_network_subnet" "test" { + parent_dn = aci_external_management_network_instance_profile.test.id + ip = "1.1.1.0/24" + annotations = [] + tags = [] +} +` diff --git a/internal/provider/resource_aci_l3out_consumer_label.go b/internal/provider/resource_aci_l3out_consumer_label.go index 9438dc3b5..d238d5ef4 100644 --- a/internal/provider/resource_aci_l3out_consumer_label.go +++ b/internal/provider/resource_aci_l3out_consumer_label.go @@ -14,11 +14,13 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -42,16 +44,52 @@ type L3extConsLblResource struct { // L3extConsLblResourceModel describes the resource data model. type L3extConsLblResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - Owner types.String `tfsdk:"owner"` - OwnerKey types.String `tfsdk:"owner_key"` - OwnerTag types.String `tfsdk:"owner_tag"` - Tag types.String `tfsdk:"tag"` + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + Owner types.String `tfsdk:"owner"` + OwnerKey types.String `tfsdk:"owner_key"` + OwnerTag types.String `tfsdk:"owner_tag"` + Tag types.String `tfsdk:"tag"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` +} + +// TagAnnotationL3extConsLblResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationL3extConsLblResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationL3extConsLblResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationL3extConsLblResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationL3extConsLblResourceModelAttributeTypes()) +} + +// TagTagL3extConsLblResourceModel describes the resource data model for the children without relation ships. +type TagTagL3extConsLblResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagL3extConsLblResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagL3extConsLblResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagL3extConsLblResourceModelAttributeTypes()) } type L3extConsLblIdentifier struct { @@ -165,6 +203,62 @@ func (r *L3extConsLblResource) Schema(ctx context.Context, req resource.SchemaRe }, MarkdownDescription: `Specifies the color of a policy label.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of resource: aci_l3out_consumer_label") @@ -194,6 +288,11 @@ func (r *L3extConsLblResource) Configure(ctx context.Context, req resource.Confi func (r *L3extConsLblResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_l3out_consumer_label") + // On create retrieve information on current state prior to making any changes in order to determine child delete operations + var stateData *L3extConsLblResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) + setL3extConsLblId(ctx, stateData) + getAndSetL3extConsLblAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *L3extConsLblResourceModel @@ -208,7 +307,13 @@ func (r *L3extConsLblResource) Create(ctx context.Context, req resource.CreateRe tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_l3out_consumer_label with id '%s'", data.Id.ValueString())) - jsonPayload := getL3extConsLblCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extConsLblResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagL3extConsLblResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getL3extConsLblCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -255,9 +360,11 @@ func (r *L3extConsLblResource) Read(ctx context.Context, req resource.ReadReques func (r *L3extConsLblResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_l3out_consumer_label") var data *L3extConsLblResourceModel + var stateData *L3extConsLblResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -265,7 +372,13 @@ func (r *L3extConsLblResource) Update(ctx context.Context, req resource.UpdateRe tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_l3out_consumer_label with id '%s'", data.Id.ValueString())) - jsonPayload := getL3extConsLblCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extConsLblResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagL3extConsLblResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getL3extConsLblCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -319,7 +432,7 @@ func (r *L3extConsLblResource) ImportState(ctx context.Context, req resource.Imp } func getAndSetL3extConsLblAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *L3extConsLblResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "l3extConsLbl,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -382,6 +495,47 @@ func getAndSetL3extConsLblAttributes(ctx context.Context, diags *diag.Diagnostic if data.Tag.IsUnknown() { data.Tag = types.StringNull() } + TagAnnotationL3extConsLbl := TagAnnotationL3extConsLblResourceModel{} + TagAnnotationL3extConsLblList := make([]TagAnnotationL3extConsLblResourceModel, 0) + TagTagL3extConsLbl := TagTagL3extConsLblResourceModel{} + TagTagL3extConsLblList := make([]TagTagL3extConsLblResourceModel, 0) + _, ok := classReadInfo[0].(map[string]interface{})["children"] + if ok { + children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) + for _, child := range children { + for childClassName, childClassDetails := range child.(map[string]interface{}) { + childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) + if childClassName == "tagAnnotation" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagAnnotationL3extConsLbl.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationL3extConsLbl.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagAnnotationL3extConsLblList = append(TagAnnotationL3extConsLblList, TagAnnotationL3extConsLbl) + } + if childClassName == "tagTag" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagTagL3extConsLbl.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagL3extConsLbl.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagTagL3extConsLblList = append(TagTagL3extConsLblList, TagTagL3extConsLbl) + } + } + } + } + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationL3extConsLblList) + data.TagAnnotation = tagAnnotationSet + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagL3extConsLblList) + data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -424,9 +578,102 @@ func setL3extConsLblId(ctx context.Context, data *L3extConsLblResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getL3extConsLblCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel) *container.Container { +func getL3extConsLblTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagAnnotationL3extConsLblPlan, tagAnnotationL3extConsLblState []TagAnnotationL3extConsLblResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationL3extConsLbl := range tagAnnotationL3extConsLblPlan { + childMap := NewAciObject() + if !tagAnnotationL3extConsLbl.Key.IsNull() && !tagAnnotationL3extConsLbl.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationL3extConsLbl.Key.ValueString() + } + if !tagAnnotationL3extConsLbl.Value.IsNull() && !tagAnnotationL3extConsLbl.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationL3extConsLbl.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationL3extConsLbl.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotation := range tagAnnotationL3extConsLblState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotation.Key { + delete = false + break + } + } + if delete { + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) + } + } + } else { + data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) + } + + return childPayloads +} + +func getL3extConsLblTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagTagL3extConsLblPlan, tagTagL3extConsLblState []TagTagL3extConsLblResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagL3extConsLbl := range tagTagL3extConsLblPlan { + childMap := NewAciObject() + if !tagTagL3extConsLbl.Key.IsNull() && !tagTagL3extConsLbl.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagL3extConsLbl.Key.ValueString() + } + if !tagTagL3extConsLbl.Value.IsNull() && !tagTagL3extConsLbl.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagL3extConsLbl.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagL3extConsLbl.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTag := range tagTagL3extConsLblState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTag.Key { + delete = false + break + } + } + if delete { + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) + } + } + } else { + data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) + } + + return childPayloads +} + +func getL3extConsLblCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *L3extConsLblResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extConsLblResourceModel, tagTagPlan, tagTagState []TagTagL3extConsLblResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} + childPayloads := []map[string]interface{}{} + + TagAnnotationchildPayloads := getL3extConsLblTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) + if TagAnnotationchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + + TagTagchildPayloads := getL3extConsLblTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) + if TagTagchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagTagchildPayloads...) + + payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_l3out_consumer_label_test.go b/internal/provider/resource_aci_l3out_consumer_label_test.go index f6c3bed49..01a8459da 100644 --- a/internal/provider/resource_aci_l3out_consumer_label_test.go +++ b/internal/provider/resource_aci_l3out_consumer_label_test.go @@ -85,6 +85,92 @@ func TestAccResourceL3extConsLblWithL3extOut(t *testing.T) { resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tag", "yellow-green"), ), }, + // Update with children + { + Config: testConfigL3extConsLblChildrenDependencyWithL3extOut, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "name", "test_name"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "description", ""), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "owner", "infra"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tag", "yellow-green"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.1.value", "value_2"), + ), + }, + // Import testing with children + { + ResourceName: "aci_l3out_consumer_label.test", + ImportState: true, + ImportStateVerify: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "name", "test_name"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "description", ""), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "owner", "infra"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tag", "yellow-green"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.1.value", "value_2"), + ), + }, + // Update with children removed from config + { + Config: testConfigL3extConsLblChildrenRemoveFromConfigDependencyWithL3extOut, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.#", "2"), + ), + }, + // Update with children first child removed + { + Config: testConfigL3extConsLblChildrenRemoveOneDependencyWithL3extOut, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.#", "1"), + ), + }, + // Update with all children removed + { + Config: testConfigL3extConsLblChildrenRemoveAllDependencyWithL3extOut, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.#", "0"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.#", "0"), + ), + }, }, }) } @@ -123,3 +209,64 @@ resource "aci_l3out_consumer_label" "test" { tag = "yellow-green" } ` +const testConfigL3extConsLblChildrenDependencyWithL3extOut = testConfigL3extOutMin + ` +resource "aci_l3out_consumer_label" "test" { + parent_dn = aci_l3_outside.test.id + name = "test_name" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigL3extConsLblChildrenRemoveFromConfigDependencyWithL3extOut = testConfigL3extOutMin + ` +resource "aci_l3out_consumer_label" "test" { + parent_dn = aci_l3_outside.test.id + name = "test_name" +} +` + +const testConfigL3extConsLblChildrenRemoveOneDependencyWithL3extOut = testConfigL3extOutMin + ` +resource "aci_l3out_consumer_label" "test" { + parent_dn = aci_l3_outside.test.id + name = "test_name" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigL3extConsLblChildrenRemoveAllDependencyWithL3extOut = testConfigL3extOutMin + ` +resource "aci_l3out_consumer_label" "test" { + parent_dn = aci_l3_outside.test.id + name = "test_name" + annotations = [] + tags = [] +} +` diff --git a/internal/provider/resource_aci_l3out_redistribute_policy.go b/internal/provider/resource_aci_l3out_redistribute_policy.go index 6abda8063..9216abc14 100644 --- a/internal/provider/resource_aci_l3out_redistribute_policy.go +++ b/internal/provider/resource_aci_l3out_redistribute_policy.go @@ -14,11 +14,13 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -47,6 +49,42 @@ type L3extRsRedistributePolResourceModel struct { Annotation types.String `tfsdk:"annotation"` Src types.String `tfsdk:"source"` TnRtctrlProfileName types.String `tfsdk:"route_control_profile_name"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` +} + +// TagAnnotationL3extRsRedistributePolResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationL3extRsRedistributePolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationL3extRsRedistributePolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationL3extRsRedistributePolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationL3extRsRedistributePolResourceModelAttributeTypes()) +} + +// TagTagL3extRsRedistributePolResourceModel describes the resource data model for the children without relation ships. +type TagTagL3extRsRedistributePolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagL3extRsRedistributePolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagL3extRsRedistributePolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagL3extRsRedistributePolResourceModelAttributeTypes()) } type L3extRsRedistributePolIdentifier struct { @@ -113,6 +151,62 @@ func (r *L3extRsRedistributePolResource) Schema(ctx context.Context, req resourc }, MarkdownDescription: `The name of the Route Control Profile object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of resource: aci_l3out_redistribute_policy") @@ -142,6 +236,11 @@ func (r *L3extRsRedistributePolResource) Configure(ctx context.Context, req reso func (r *L3extRsRedistributePolResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_l3out_redistribute_policy") + // On create retrieve information on current state prior to making any changes in order to determine child delete operations + var stateData *L3extRsRedistributePolResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) + setL3extRsRedistributePolId(ctx, stateData) + getAndSetL3extRsRedistributePolAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *L3extRsRedistributePolResourceModel @@ -156,7 +255,13 @@ func (r *L3extRsRedistributePolResource) Create(ctx context.Context, req resourc tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_l3out_redistribute_policy with id '%s'", data.Id.ValueString())) - jsonPayload := getL3extRsRedistributePolCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsRedistributePolResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagL3extRsRedistributePolResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getL3extRsRedistributePolCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -203,9 +308,11 @@ func (r *L3extRsRedistributePolResource) Read(ctx context.Context, req resource. func (r *L3extRsRedistributePolResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_l3out_redistribute_policy") var data *L3extRsRedistributePolResourceModel + var stateData *L3extRsRedistributePolResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -213,7 +320,13 @@ func (r *L3extRsRedistributePolResource) Update(ctx context.Context, req resourc tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_l3out_redistribute_policy with id '%s'", data.Id.ValueString())) - jsonPayload := getL3extRsRedistributePolCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsRedistributePolResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagL3extRsRedistributePolResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getL3extRsRedistributePolCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -267,7 +380,7 @@ func (r *L3extRsRedistributePolResource) ImportState(ctx context.Context, req re } func getAndSetL3extRsRedistributePolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *L3extRsRedistributePolResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "l3extRsRedistributePol,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -300,6 +413,47 @@ func getAndSetL3extRsRedistributePolAttributes(ctx context.Context, diags *diag. if data.TnRtctrlProfileName.IsUnknown() { data.TnRtctrlProfileName = types.StringNull() } + TagAnnotationL3extRsRedistributePol := TagAnnotationL3extRsRedistributePolResourceModel{} + TagAnnotationL3extRsRedistributePolList := make([]TagAnnotationL3extRsRedistributePolResourceModel, 0) + TagTagL3extRsRedistributePol := TagTagL3extRsRedistributePolResourceModel{} + TagTagL3extRsRedistributePolList := make([]TagTagL3extRsRedistributePolResourceModel, 0) + _, ok := classReadInfo[0].(map[string]interface{})["children"] + if ok { + children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) + for _, child := range children { + for childClassName, childClassDetails := range child.(map[string]interface{}) { + childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) + if childClassName == "tagAnnotation" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagAnnotationL3extRsRedistributePol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationL3extRsRedistributePol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagAnnotationL3extRsRedistributePolList = append(TagAnnotationL3extRsRedistributePolList, TagAnnotationL3extRsRedistributePol) + } + if childClassName == "tagTag" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagTagL3extRsRedistributePol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagL3extRsRedistributePol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagTagL3extRsRedistributePolList = append(TagTagL3extRsRedistributePolList, TagTagL3extRsRedistributePol) + } + } + } + } + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationL3extRsRedistributePolList) + data.TagAnnotation = tagAnnotationSet + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagL3extRsRedistributePolList) + data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -342,9 +496,102 @@ func setL3extRsRedistributePolId(ctx context.Context, data *L3extRsRedistributeP data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getL3extRsRedistributePolCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel) *container.Container { +func getL3extRsRedistributePolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagAnnotationL3extRsRedistributePolPlan, tagAnnotationL3extRsRedistributePolState []TagAnnotationL3extRsRedistributePolResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationL3extRsRedistributePol := range tagAnnotationL3extRsRedistributePolPlan { + childMap := NewAciObject() + if !tagAnnotationL3extRsRedistributePol.Key.IsNull() && !tagAnnotationL3extRsRedistributePol.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationL3extRsRedistributePol.Key.ValueString() + } + if !tagAnnotationL3extRsRedistributePol.Value.IsNull() && !tagAnnotationL3extRsRedistributePol.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationL3extRsRedistributePol.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationL3extRsRedistributePol.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotation := range tagAnnotationL3extRsRedistributePolState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotation.Key { + delete = false + break + } + } + if delete { + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) + } + } + } else { + data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) + } + + return childPayloads +} + +func getL3extRsRedistributePolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagTagL3extRsRedistributePolPlan, tagTagL3extRsRedistributePolState []TagTagL3extRsRedistributePolResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagL3extRsRedistributePol := range tagTagL3extRsRedistributePolPlan { + childMap := NewAciObject() + if !tagTagL3extRsRedistributePol.Key.IsNull() && !tagTagL3extRsRedistributePol.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagL3extRsRedistributePol.Key.ValueString() + } + if !tagTagL3extRsRedistributePol.Value.IsNull() && !tagTagL3extRsRedistributePol.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagL3extRsRedistributePol.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagL3extRsRedistributePol.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTag := range tagTagL3extRsRedistributePolState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTag.Key { + delete = false + break + } + } + if delete { + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) + } + } + } else { + data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) + } + + return childPayloads +} + +func getL3extRsRedistributePolCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *L3extRsRedistributePolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsRedistributePolResourceModel, tagTagPlan, tagTagState []TagTagL3extRsRedistributePolResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} + childPayloads := []map[string]interface{}{} + + TagAnnotationchildPayloads := getL3extRsRedistributePolTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) + if TagAnnotationchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + + TagTagchildPayloads := getL3extRsRedistributePolTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) + if TagTagchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagTagchildPayloads...) + + payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_l3out_redistribute_policy_test.go b/internal/provider/resource_aci_l3out_redistribute_policy_test.go index 5acd30270..dae8b08af 100644 --- a/internal/provider/resource_aci_l3out_redistribute_policy_test.go +++ b/internal/provider/resource_aci_l3out_redistribute_policy_test.go @@ -66,6 +66,82 @@ func TestAccResourceL3extRsRedistributePolWithL3extOut(t *testing.T) { resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotation", "orchestrator:terraform"), ), }, + // Update with children + { + Config: testConfigL3extRsRedistributePolChildrenDependencyWithL3extOut, + ExpectNonEmptyPlan: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "route_control_profile_name", "test_tn_rtctrl_profile_name"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "source", "direct"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.1.value", "value_2"), + ), + }, + // Import testing with children + { + ResourceName: "aci_l3out_redistribute_policy.test", + ImportState: true, + ImportStateVerify: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "route_control_profile_name", "test_tn_rtctrl_profile_name"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "source", "direct"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.1.value", "value_2"), + ), + }, + // Update with children removed from config + { + Config: testConfigL3extRsRedistributePolChildrenRemoveFromConfigDependencyWithL3extOut, + ExpectNonEmptyPlan: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.#", "2"), + ), + }, + // Update with children first child removed + { + Config: testConfigL3extRsRedistributePolChildrenRemoveOneDependencyWithL3extOut, + ExpectNonEmptyPlan: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.#", "1"), + ), + }, + // Update with all children removed + { + Config: testConfigL3extRsRedistributePolChildrenRemoveAllDependencyWithL3extOut, + ExpectNonEmptyPlan: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.#", "0"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.#", "0"), + ), + }, }, }) } @@ -95,3 +171,68 @@ resource "aci_l3out_redistribute_policy" "test" { source = "direct" } ` +const testConfigL3extRsRedistributePolChildrenDependencyWithL3extOut = testConfigL3extOutMinDependencyWithFvTenant + ` +resource "aci_l3out_redistribute_policy" "test" { + parent_dn = aci_l3_outside.test.id + route_control_profile_name = "test_tn_rtctrl_profile_name" + source = "direct" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigL3extRsRedistributePolChildrenRemoveFromConfigDependencyWithL3extOut = testConfigL3extOutMinDependencyWithFvTenant + ` +resource "aci_l3out_redistribute_policy" "test" { + parent_dn = aci_l3_outside.test.id + route_control_profile_name = "test_tn_rtctrl_profile_name" + source = "direct" +} +` + +const testConfigL3extRsRedistributePolChildrenRemoveOneDependencyWithL3extOut = testConfigL3extOutMinDependencyWithFvTenant + ` +resource "aci_l3out_redistribute_policy" "test" { + parent_dn = aci_l3_outside.test.id + route_control_profile_name = "test_tn_rtctrl_profile_name" + source = "direct" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigL3extRsRedistributePolChildrenRemoveAllDependencyWithL3extOut = testConfigL3extOutMinDependencyWithFvTenant + ` +resource "aci_l3out_redistribute_policy" "test" { + parent_dn = aci_l3_outside.test.id + route_control_profile_name = "test_tn_rtctrl_profile_name" + source = "direct" + annotations = [] + tags = [] +} +` diff --git a/internal/provider/resource_aci_out_of_band_contract.go b/internal/provider/resource_aci_out_of_band_contract.go index 62b6ed3a4..650b6c994 100644 --- a/internal/provider/resource_aci_out_of_band_contract.go +++ b/internal/provider/resource_aci_out_of_band_contract.go @@ -14,11 +14,13 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -42,17 +44,53 @@ type VzOOBBrCPResource struct { // VzOOBBrCPResourceModel describes the resource data model. type VzOOBBrCPResourceModel struct { - Id types.String `tfsdk:"id"` - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Intent types.String `tfsdk:"intent"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - OwnerKey types.String `tfsdk:"owner_key"` - OwnerTag types.String `tfsdk:"owner_tag"` - Prio types.String `tfsdk:"priority"` - Scope types.String `tfsdk:"scope"` - TargetDscp types.String `tfsdk:"target_dscp"` + Id types.String `tfsdk:"id"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Intent types.String `tfsdk:"intent"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + OwnerKey types.String `tfsdk:"owner_key"` + OwnerTag types.String `tfsdk:"owner_tag"` + Prio types.String `tfsdk:"priority"` + Scope types.String `tfsdk:"scope"` + TargetDscp types.String `tfsdk:"target_dscp"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` +} + +// TagAnnotationVzOOBBrCPResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationVzOOBBrCPResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationVzOOBBrCPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationVzOOBBrCPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationVzOOBBrCPResourceModelAttributeTypes()) +} + +// TagTagVzOOBBrCPResourceModel describes the resource data model for the children without relation ships. +type TagTagVzOOBBrCPResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagVzOOBBrCPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagVzOOBBrCPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagVzOOBBrCPResourceModelAttributeTypes()) } type VzOOBBrCPIdentifier struct { @@ -182,6 +220,62 @@ func (r *VzOOBBrCPResource) Schema(ctx context.Context, req resource.SchemaReque }, MarkdownDescription: `The target DSCP value of the Out Of Band Contract object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of resource: aci_out_of_band_contract") @@ -211,6 +305,11 @@ func (r *VzOOBBrCPResource) Configure(ctx context.Context, req resource.Configur func (r *VzOOBBrCPResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_out_of_band_contract") + // On create retrieve information on current state prior to making any changes in order to determine child delete operations + var stateData *VzOOBBrCPResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) + setVzOOBBrCPId(ctx, stateData) + getAndSetVzOOBBrCPAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *VzOOBBrCPResourceModel @@ -225,7 +324,13 @@ func (r *VzOOBBrCPResource) Create(ctx context.Context, req resource.CreateReque tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_out_of_band_contract with id '%s'", data.Id.ValueString())) - jsonPayload := getVzOOBBrCPCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationVzOOBBrCPResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagVzOOBBrCPResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getVzOOBBrCPCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -272,9 +377,11 @@ func (r *VzOOBBrCPResource) Read(ctx context.Context, req resource.ReadRequest, func (r *VzOOBBrCPResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_out_of_band_contract") var data *VzOOBBrCPResourceModel + var stateData *VzOOBBrCPResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -282,7 +389,13 @@ func (r *VzOOBBrCPResource) Update(ctx context.Context, req resource.UpdateReque tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_out_of_band_contract with id '%s'", data.Id.ValueString())) - jsonPayload := getVzOOBBrCPCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationVzOOBBrCPResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagVzOOBBrCPResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getVzOOBBrCPCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -336,7 +449,7 @@ func (r *VzOOBBrCPResource) ImportState(ctx context.Context, req resource.Import } func getAndSetVzOOBBrCPAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *VzOOBBrCPResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "vzOOBBrCP,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -410,6 +523,47 @@ func getAndSetVzOOBBrCPAttributes(ctx context.Context, diags *diag.Diagnostics, if data.TargetDscp.IsUnknown() { data.TargetDscp = types.StringNull() } + TagAnnotationVzOOBBrCP := TagAnnotationVzOOBBrCPResourceModel{} + TagAnnotationVzOOBBrCPList := make([]TagAnnotationVzOOBBrCPResourceModel, 0) + TagTagVzOOBBrCP := TagTagVzOOBBrCPResourceModel{} + TagTagVzOOBBrCPList := make([]TagTagVzOOBBrCPResourceModel, 0) + _, ok := classReadInfo[0].(map[string]interface{})["children"] + if ok { + children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) + for _, child := range children { + for childClassName, childClassDetails := range child.(map[string]interface{}) { + childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) + if childClassName == "tagAnnotation" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagAnnotationVzOOBBrCP.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationVzOOBBrCP.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagAnnotationVzOOBBrCPList = append(TagAnnotationVzOOBBrCPList, TagAnnotationVzOOBBrCP) + } + if childClassName == "tagTag" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagTagVzOOBBrCP.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagVzOOBBrCP.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagTagVzOOBBrCPList = append(TagTagVzOOBBrCPList, TagTagVzOOBBrCP) + } + } + } + } + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationVzOOBBrCPList) + data.TagAnnotation = tagAnnotationSet + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagVzOOBBrCPList) + data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -436,9 +590,102 @@ func setVzOOBBrCPId(ctx context.Context, data *VzOOBBrCPResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", strings.Split([]string{"uni/tn-mgmt/oobbrc-{name}"}[0], "/")[0], rn)) } -func getVzOOBBrCPCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel) *container.Container { +func getVzOOBBrCPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagAnnotationVzOOBBrCPPlan, tagAnnotationVzOOBBrCPState []TagAnnotationVzOOBBrCPResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationVzOOBBrCP := range tagAnnotationVzOOBBrCPPlan { + childMap := NewAciObject() + if !tagAnnotationVzOOBBrCP.Key.IsNull() && !tagAnnotationVzOOBBrCP.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationVzOOBBrCP.Key.ValueString() + } + if !tagAnnotationVzOOBBrCP.Value.IsNull() && !tagAnnotationVzOOBBrCP.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationVzOOBBrCP.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationVzOOBBrCP.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotation := range tagAnnotationVzOOBBrCPState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotation.Key { + delete = false + break + } + } + if delete { + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) + } + } + } else { + data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) + } + + return childPayloads +} + +func getVzOOBBrCPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagTagVzOOBBrCPPlan, tagTagVzOOBBrCPState []TagTagVzOOBBrCPResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagVzOOBBrCP := range tagTagVzOOBBrCPPlan { + childMap := NewAciObject() + if !tagTagVzOOBBrCP.Key.IsNull() && !tagTagVzOOBBrCP.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagVzOOBBrCP.Key.ValueString() + } + if !tagTagVzOOBBrCP.Value.IsNull() && !tagTagVzOOBBrCP.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagVzOOBBrCP.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagVzOOBBrCP.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTag := range tagTagVzOOBBrCPState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTag.Key { + delete = false + break + } + } + if delete { + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) + } + } + } else { + data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) + } + + return childPayloads +} + +func getVzOOBBrCPCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *VzOOBBrCPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationVzOOBBrCPResourceModel, tagTagPlan, tagTagState []TagTagVzOOBBrCPResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} + childPayloads := []map[string]interface{}{} + + TagAnnotationchildPayloads := getVzOOBBrCPTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) + if TagAnnotationchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + + TagTagchildPayloads := getVzOOBBrCPTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) + if TagTagchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagTagchildPayloads...) + + payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_out_of_band_contract_test.go b/internal/provider/resource_aci_out_of_band_contract_test.go index da850a413..baabe7f5c 100644 --- a/internal/provider/resource_aci_out_of_band_contract_test.go +++ b/internal/provider/resource_aci_out_of_band_contract_test.go @@ -98,6 +98,94 @@ func TestAccResourceVzOOBBrCP(t *testing.T) { resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "target_dscp", "unspecified"), ), }, + // Update with children + { + Config: testConfigVzOOBBrCPChildren, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "description", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "intent", "install"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "priority", "unspecified"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "scope", "context"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "target_dscp", "unspecified"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.#", "2"), + ), + }, + // Update with children removed from config + { + Config: testConfigVzOOBBrCPChildrenRemoveFromConfig, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "description", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "intent", "install"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "priority", "unspecified"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "scope", "context"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "target_dscp", "unspecified"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.#", "2"), + ), + }, + // Update with children first child removed + { + Config: testConfigVzOOBBrCPChildrenRemoveOne, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "description", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "intent", "install"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "priority", "unspecified"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "scope", "context"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "target_dscp", "unspecified"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.#", "1"), + ), + }, + // Update with all children removed + { + Config: testConfigVzOOBBrCPChildrenRemoveAll, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "description", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "intent", "install"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "priority", "unspecified"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "scope", "context"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "target_dscp", "unspecified"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.#", "0"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.#", "0"), + ), + }, }, }) } @@ -137,3 +225,60 @@ resource "aci_out_of_band_contract" "test" { target_dscp = "unspecified" } ` +const testConfigVzOOBBrCPChildren = ` +resource "aci_out_of_band_contract" "test" { + name = "test_name" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigVzOOBBrCPChildrenRemoveFromConfig = ` +resource "aci_out_of_band_contract" "test" { + name = "test_name" +} +` + +const testConfigVzOOBBrCPChildrenRemoveOne = ` +resource "aci_out_of_band_contract" "test" { + name = "test_name" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigVzOOBBrCPChildrenRemoveAll = ` +resource "aci_out_of_band_contract" "test" { + name = "test_name" + annotations = [] + tags = [] +} +` diff --git a/internal/provider/resource_aci_pim_route_map_entry.go b/internal/provider/resource_aci_pim_route_map_entry.go index d508b7290..51563b093 100644 --- a/internal/provider/resource_aci_pim_route_map_entry.go +++ b/internal/provider/resource_aci_pim_route_map_entry.go @@ -14,11 +14,13 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -42,17 +44,53 @@ type PimRouteMapEntryResource struct { // PimRouteMapEntryResourceModel describes the resource data model. type PimRouteMapEntryResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Action types.String `tfsdk:"action"` - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Grp types.String `tfsdk:"group_ip"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - Order types.String `tfsdk:"order"` - Rp types.String `tfsdk:"rendezvous_point_ip"` - Src types.String `tfsdk:"source_ip"` + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Action types.String `tfsdk:"action"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Grp types.String `tfsdk:"group_ip"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + Order types.String `tfsdk:"order"` + Rp types.String `tfsdk:"rendezvous_point_ip"` + Src types.String `tfsdk:"source_ip"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` +} + +// TagAnnotationPimRouteMapEntryResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationPimRouteMapEntryResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationPimRouteMapEntryResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationPimRouteMapEntryResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationPimRouteMapEntryResourceModelAttributeTypes()) +} + +// TagTagPimRouteMapEntryResourceModel describes the resource data model for the children without relation ships. +type TagTagPimRouteMapEntryResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagPimRouteMapEntryResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagPimRouteMapEntryResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagPimRouteMapEntryResourceModelAttributeTypes()) } type PimRouteMapEntryIdentifier struct { @@ -172,6 +210,62 @@ func (r *PimRouteMapEntryResource) Schema(ctx context.Context, req resource.Sche }, MarkdownDescription: `The source ip of the Pim Route Map Entry object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of resource: aci_pim_route_map_entry") @@ -201,6 +295,11 @@ func (r *PimRouteMapEntryResource) Configure(ctx context.Context, req resource.C func (r *PimRouteMapEntryResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_pim_route_map_entry") + // On create retrieve information on current state prior to making any changes in order to determine child delete operations + var stateData *PimRouteMapEntryResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) + setPimRouteMapEntryId(ctx, stateData) + getAndSetPimRouteMapEntryAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *PimRouteMapEntryResourceModel @@ -215,7 +314,13 @@ func (r *PimRouteMapEntryResource) Create(ctx context.Context, req resource.Crea tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_pim_route_map_entry with id '%s'", data.Id.ValueString())) - jsonPayload := getPimRouteMapEntryCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapEntryResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagPimRouteMapEntryResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getPimRouteMapEntryCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -262,9 +367,11 @@ func (r *PimRouteMapEntryResource) Read(ctx context.Context, req resource.ReadRe func (r *PimRouteMapEntryResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_pim_route_map_entry") var data *PimRouteMapEntryResourceModel + var stateData *PimRouteMapEntryResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -272,7 +379,13 @@ func (r *PimRouteMapEntryResource) Update(ctx context.Context, req resource.Upda tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_pim_route_map_entry with id '%s'", data.Id.ValueString())) - jsonPayload := getPimRouteMapEntryCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapEntryResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagPimRouteMapEntryResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getPimRouteMapEntryCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -326,7 +439,7 @@ func (r *PimRouteMapEntryResource) ImportState(ctx context.Context, req resource } func getAndSetPimRouteMapEntryAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *PimRouteMapEntryResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "pimRouteMapEntry,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -395,6 +508,47 @@ func getAndSetPimRouteMapEntryAttributes(ctx context.Context, diags *diag.Diagno if data.Src.IsUnknown() { data.Src = types.StringNull() } + TagAnnotationPimRouteMapEntry := TagAnnotationPimRouteMapEntryResourceModel{} + TagAnnotationPimRouteMapEntryList := make([]TagAnnotationPimRouteMapEntryResourceModel, 0) + TagTagPimRouteMapEntry := TagTagPimRouteMapEntryResourceModel{} + TagTagPimRouteMapEntryList := make([]TagTagPimRouteMapEntryResourceModel, 0) + _, ok := classReadInfo[0].(map[string]interface{})["children"] + if ok { + children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) + for _, child := range children { + for childClassName, childClassDetails := range child.(map[string]interface{}) { + childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) + if childClassName == "tagAnnotation" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagAnnotationPimRouteMapEntry.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationPimRouteMapEntry.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagAnnotationPimRouteMapEntryList = append(TagAnnotationPimRouteMapEntryList, TagAnnotationPimRouteMapEntry) + } + if childClassName == "tagTag" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagTagPimRouteMapEntry.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagPimRouteMapEntry.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagTagPimRouteMapEntryList = append(TagTagPimRouteMapEntryList, TagTagPimRouteMapEntry) + } + } + } + } + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationPimRouteMapEntryList) + data.TagAnnotation = tagAnnotationSet + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagPimRouteMapEntryList) + data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -437,9 +591,102 @@ func setPimRouteMapEntryId(ctx context.Context, data *PimRouteMapEntryResourceMo data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getPimRouteMapEntryCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel) *container.Container { +func getPimRouteMapEntryTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagAnnotationPimRouteMapEntryPlan, tagAnnotationPimRouteMapEntryState []TagAnnotationPimRouteMapEntryResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationPimRouteMapEntry := range tagAnnotationPimRouteMapEntryPlan { + childMap := NewAciObject() + if !tagAnnotationPimRouteMapEntry.Key.IsNull() && !tagAnnotationPimRouteMapEntry.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationPimRouteMapEntry.Key.ValueString() + } + if !tagAnnotationPimRouteMapEntry.Value.IsNull() && !tagAnnotationPimRouteMapEntry.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationPimRouteMapEntry.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationPimRouteMapEntry.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotation := range tagAnnotationPimRouteMapEntryState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotation.Key { + delete = false + break + } + } + if delete { + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) + } + } + } else { + data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) + } + + return childPayloads +} + +func getPimRouteMapEntryTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagTagPimRouteMapEntryPlan, tagTagPimRouteMapEntryState []TagTagPimRouteMapEntryResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagPimRouteMapEntry := range tagTagPimRouteMapEntryPlan { + childMap := NewAciObject() + if !tagTagPimRouteMapEntry.Key.IsNull() && !tagTagPimRouteMapEntry.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagPimRouteMapEntry.Key.ValueString() + } + if !tagTagPimRouteMapEntry.Value.IsNull() && !tagTagPimRouteMapEntry.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagPimRouteMapEntry.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagPimRouteMapEntry.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTag := range tagTagPimRouteMapEntryState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTag.Key { + delete = false + break + } + } + if delete { + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) + } + } + } else { + data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) + } + + return childPayloads +} + +func getPimRouteMapEntryCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapEntryResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapEntryResourceModel, tagTagPlan, tagTagState []TagTagPimRouteMapEntryResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} + childPayloads := []map[string]interface{}{} + + TagAnnotationchildPayloads := getPimRouteMapEntryTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) + if TagAnnotationchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + + TagTagchildPayloads := getPimRouteMapEntryTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) + if TagTagchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagTagchildPayloads...) + + payloadMap["children"] = childPayloads if !data.Action.IsNull() && !data.Action.IsUnknown() { payloadMap["attributes"].(map[string]string)["action"] = data.Action.ValueString() } diff --git a/internal/provider/resource_aci_pim_route_map_entry_test.go b/internal/provider/resource_aci_pim_route_map_entry_test.go index f9f5eeaf5..162dade9a 100644 --- a/internal/provider/resource_aci_pim_route_map_entry_test.go +++ b/internal/provider/resource_aci_pim_route_map_entry_test.go @@ -89,6 +89,94 @@ func TestAccResourcePimRouteMapEntryWithPimRouteMapPol(t *testing.T) { resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "source_ip", "0.0.0.0"), ), }, + // Update with children + { + Config: testConfigPimRouteMapEntryChildrenDependencyWithPimRouteMapPol, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "order", "1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "action", "permit"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "description", ""), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "group_ip", "0.0.0.0"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "name", ""), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "rendezvous_point_ip", "0.0.0.0"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "source_ip", "0.0.0.0"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.1.value", "value_2"), + ), + }, + // Import testing with children + { + ResourceName: "aci_pim_route_map_entry.test", + ImportState: true, + ImportStateVerify: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "order", "1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "action", "permit"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "description", ""), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "group_ip", "0.0.0.0"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "name", ""), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "rendezvous_point_ip", "0.0.0.0"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "source_ip", "0.0.0.0"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.1.value", "value_2"), + ), + }, + // Update with children removed from config + { + Config: testConfigPimRouteMapEntryChildrenRemoveFromConfigDependencyWithPimRouteMapPol, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.#", "2"), + ), + }, + // Update with children first child removed + { + Config: testConfigPimRouteMapEntryChildrenRemoveOneDependencyWithPimRouteMapPol, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.#", "1"), + ), + }, + // Update with all children removed + { + Config: testConfigPimRouteMapEntryChildrenRemoveAllDependencyWithPimRouteMapPol, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.#", "0"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.#", "0"), + ), + }, }, }) } @@ -129,3 +217,64 @@ resource "aci_pim_route_map_entry" "test" { source_ip = "0.0.0.0" } ` +const testConfigPimRouteMapEntryChildrenDependencyWithPimRouteMapPol = testConfigPimRouteMapPolMinDependencyWithFvTenant + ` +resource "aci_pim_route_map_entry" "test" { + parent_dn = aci_pim_route_map_policy.test.id + order = "1" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigPimRouteMapEntryChildrenRemoveFromConfigDependencyWithPimRouteMapPol = testConfigPimRouteMapPolMinDependencyWithFvTenant + ` +resource "aci_pim_route_map_entry" "test" { + parent_dn = aci_pim_route_map_policy.test.id + order = "1" +} +` + +const testConfigPimRouteMapEntryChildrenRemoveOneDependencyWithPimRouteMapPol = testConfigPimRouteMapPolMinDependencyWithFvTenant + ` +resource "aci_pim_route_map_entry" "test" { + parent_dn = aci_pim_route_map_policy.test.id + order = "1" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigPimRouteMapEntryChildrenRemoveAllDependencyWithPimRouteMapPol = testConfigPimRouteMapPolMinDependencyWithFvTenant + ` +resource "aci_pim_route_map_entry" "test" { + parent_dn = aci_pim_route_map_policy.test.id + order = "1" + annotations = [] + tags = [] +} +` diff --git a/internal/provider/resource_aci_pim_route_map_policy.go b/internal/provider/resource_aci_pim_route_map_policy.go index f34c42edf..40850566c 100644 --- a/internal/provider/resource_aci_pim_route_map_policy.go +++ b/internal/provider/resource_aci_pim_route_map_policy.go @@ -13,11 +13,13 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" @@ -40,14 +42,50 @@ type PimRouteMapPolResource struct { // PimRouteMapPolResourceModel describes the resource data model. type PimRouteMapPolResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - OwnerKey types.String `tfsdk:"owner_key"` - OwnerTag types.String `tfsdk:"owner_tag"` + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + OwnerKey types.String `tfsdk:"owner_key"` + OwnerTag types.String `tfsdk:"owner_tag"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` +} + +// TagAnnotationPimRouteMapPolResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationPimRouteMapPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationPimRouteMapPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationPimRouteMapPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationPimRouteMapPolResourceModelAttributeTypes()) +} + +// TagTagPimRouteMapPolResourceModel describes the resource data model for the children without relation ships. +type TagTagPimRouteMapPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagPimRouteMapPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagPimRouteMapPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagPimRouteMapPolResourceModelAttributeTypes()) } type PimRouteMapPolIdentifier struct { @@ -137,6 +175,62 @@ func (r *PimRouteMapPolResource) Schema(ctx context.Context, req resource.Schema }, MarkdownDescription: `A tag for enabling clients to add their own data. For example, to indicate who created this object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of resource: aci_pim_route_map_policy") @@ -166,6 +260,11 @@ func (r *PimRouteMapPolResource) Configure(ctx context.Context, req resource.Con func (r *PimRouteMapPolResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_pim_route_map_policy") + // On create retrieve information on current state prior to making any changes in order to determine child delete operations + var stateData *PimRouteMapPolResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) + setPimRouteMapPolId(ctx, stateData) + getAndSetPimRouteMapPolAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *PimRouteMapPolResourceModel @@ -180,7 +279,13 @@ func (r *PimRouteMapPolResource) Create(ctx context.Context, req resource.Create tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_pim_route_map_policy with id '%s'", data.Id.ValueString())) - jsonPayload := getPimRouteMapPolCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapPolResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagPimRouteMapPolResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getPimRouteMapPolCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -227,9 +332,11 @@ func (r *PimRouteMapPolResource) Read(ctx context.Context, req resource.ReadRequ func (r *PimRouteMapPolResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_pim_route_map_policy") var data *PimRouteMapPolResourceModel + var stateData *PimRouteMapPolResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -237,7 +344,13 @@ func (r *PimRouteMapPolResource) Update(ctx context.Context, req resource.Update tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_pim_route_map_policy with id '%s'", data.Id.ValueString())) - jsonPayload := getPimRouteMapPolCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapPolResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagPimRouteMapPolResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getPimRouteMapPolCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -291,7 +404,7 @@ func (r *PimRouteMapPolResource) ImportState(ctx context.Context, req resource.I } func getAndSetPimRouteMapPolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *PimRouteMapPolResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "pimRouteMapPol,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -342,6 +455,47 @@ func getAndSetPimRouteMapPolAttributes(ctx context.Context, diags *diag.Diagnost if data.OwnerTag.IsUnknown() { data.OwnerTag = types.StringNull() } + TagAnnotationPimRouteMapPol := TagAnnotationPimRouteMapPolResourceModel{} + TagAnnotationPimRouteMapPolList := make([]TagAnnotationPimRouteMapPolResourceModel, 0) + TagTagPimRouteMapPol := TagTagPimRouteMapPolResourceModel{} + TagTagPimRouteMapPolList := make([]TagTagPimRouteMapPolResourceModel, 0) + _, ok := classReadInfo[0].(map[string]interface{})["children"] + if ok { + children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) + for _, child := range children { + for childClassName, childClassDetails := range child.(map[string]interface{}) { + childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) + if childClassName == "tagAnnotation" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagAnnotationPimRouteMapPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationPimRouteMapPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagAnnotationPimRouteMapPolList = append(TagAnnotationPimRouteMapPolList, TagAnnotationPimRouteMapPol) + } + if childClassName == "tagTag" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagTagPimRouteMapPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagPimRouteMapPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagTagPimRouteMapPolList = append(TagTagPimRouteMapPolList, TagTagPimRouteMapPol) + } + } + } + } + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationPimRouteMapPolList) + data.TagAnnotation = tagAnnotationSet + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagPimRouteMapPolList) + data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -384,9 +538,102 @@ func setPimRouteMapPolId(ctx context.Context, data *PimRouteMapPolResourceModel) data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getPimRouteMapPolCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel) *container.Container { +func getPimRouteMapPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagAnnotationPimRouteMapPolPlan, tagAnnotationPimRouteMapPolState []TagAnnotationPimRouteMapPolResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationPimRouteMapPol := range tagAnnotationPimRouteMapPolPlan { + childMap := NewAciObject() + if !tagAnnotationPimRouteMapPol.Key.IsNull() && !tagAnnotationPimRouteMapPol.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationPimRouteMapPol.Key.ValueString() + } + if !tagAnnotationPimRouteMapPol.Value.IsNull() && !tagAnnotationPimRouteMapPol.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationPimRouteMapPol.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationPimRouteMapPol.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotation := range tagAnnotationPimRouteMapPolState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotation.Key { + delete = false + break + } + } + if delete { + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) + } + } + } else { + data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) + } + + return childPayloads +} + +func getPimRouteMapPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagTagPimRouteMapPolPlan, tagTagPimRouteMapPolState []TagTagPimRouteMapPolResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagPimRouteMapPol := range tagTagPimRouteMapPolPlan { + childMap := NewAciObject() + if !tagTagPimRouteMapPol.Key.IsNull() && !tagTagPimRouteMapPol.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagPimRouteMapPol.Key.ValueString() + } + if !tagTagPimRouteMapPol.Value.IsNull() && !tagTagPimRouteMapPol.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagPimRouteMapPol.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagPimRouteMapPol.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTag := range tagTagPimRouteMapPolState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTag.Key { + delete = false + break + } + } + if delete { + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) + } + } + } else { + data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) + } + + return childPayloads +} + +func getPimRouteMapPolCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *PimRouteMapPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationPimRouteMapPolResourceModel, tagTagPlan, tagTagState []TagTagPimRouteMapPolResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} + childPayloads := []map[string]interface{}{} + + TagAnnotationchildPayloads := getPimRouteMapPolTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) + if TagAnnotationchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + + TagTagchildPayloads := getPimRouteMapPolTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) + if TagTagchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagTagchildPayloads...) + + payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_pim_route_map_policy_test.go b/internal/provider/resource_aci_pim_route_map_policy_test.go index b3103eca3..aff79ff65 100644 --- a/internal/provider/resource_aci_pim_route_map_policy_test.go +++ b/internal/provider/resource_aci_pim_route_map_policy_test.go @@ -77,6 +77,88 @@ func TestAccResourcePimRouteMapPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "owner_tag", ""), ), }, + // Update with children + { + Config: testConfigPimRouteMapPolChildrenDependencyWithFvTenant, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "name", "test_name"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "description", ""), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.1.value", "value_2"), + ), + }, + // Import testing with children + { + ResourceName: "aci_pim_route_map_policy.test", + ImportState: true, + ImportStateVerify: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "name", "test_name"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "description", ""), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "owner_key", ""), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "owner_tag", ""), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.1.value", "value_2"), + ), + }, + // Update with children removed from config + { + Config: testConfigPimRouteMapPolChildrenRemoveFromConfigDependencyWithFvTenant, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.#", "2"), + ), + }, + // Update with children first child removed + { + Config: testConfigPimRouteMapPolChildrenRemoveOneDependencyWithFvTenant, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.#", "1"), + ), + }, + // Update with all children removed + { + Config: testConfigPimRouteMapPolChildrenRemoveAllDependencyWithFvTenant, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.#", "0"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.#", "0"), + ), + }, }, }) } @@ -111,3 +193,64 @@ resource "aci_pim_route_map_policy" "test" { owner_tag = "" } ` +const testConfigPimRouteMapPolChildrenDependencyWithFvTenant = testConfigFvTenantMin + ` +resource "aci_pim_route_map_policy" "test" { + parent_dn = aci_tenant.test.id + name = "test_name" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigPimRouteMapPolChildrenRemoveFromConfigDependencyWithFvTenant = testConfigFvTenantMin + ` +resource "aci_pim_route_map_policy" "test" { + parent_dn = aci_tenant.test.id + name = "test_name" +} +` + +const testConfigPimRouteMapPolChildrenRemoveOneDependencyWithFvTenant = testConfigFvTenantMin + ` +resource "aci_pim_route_map_policy" "test" { + parent_dn = aci_tenant.test.id + name = "test_name" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigPimRouteMapPolChildrenRemoveAllDependencyWithFvTenant = testConfigFvTenantMin + ` +resource "aci_pim_route_map_policy" "test" { + parent_dn = aci_tenant.test.id + name = "test_name" + annotations = [] + tags = [] +} +` diff --git a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go index 3fee1af19..30d9cc184 100644 --- a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go +++ b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract.go @@ -14,11 +14,13 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -47,6 +49,42 @@ type MgmtRsOoBConsResourceModel struct { Annotation types.String `tfsdk:"annotation"` Prio types.String `tfsdk:"priority"` TnVzOOBBrCPName types.String `tfsdk:"out_of_band_contract_name"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` +} + +// TagAnnotationMgmtRsOoBConsResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationMgmtRsOoBConsResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationMgmtRsOoBConsResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationMgmtRsOoBConsResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMgmtRsOoBConsResourceModelAttributeTypes()) +} + +// TagTagMgmtRsOoBConsResourceModel describes the resource data model for the children without relation ships. +type TagTagMgmtRsOoBConsResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagMgmtRsOoBConsResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagMgmtRsOoBConsResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMgmtRsOoBConsResourceModelAttributeTypes()) } type MgmtRsOoBConsIdentifier struct { @@ -112,6 +150,62 @@ func (r *MgmtRsOoBConsResource) Schema(ctx context.Context, req resource.SchemaR }, MarkdownDescription: `The name of the Out Of Band Contract object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of resource: aci_relation_to_consumed_out_of_band_contract") @@ -141,6 +235,11 @@ func (r *MgmtRsOoBConsResource) Configure(ctx context.Context, req resource.Conf func (r *MgmtRsOoBConsResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_relation_to_consumed_out_of_band_contract") + // On create retrieve information on current state prior to making any changes in order to determine child delete operations + var stateData *MgmtRsOoBConsResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) + setMgmtRsOoBConsId(ctx, stateData) + getAndSetMgmtRsOoBConsAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *MgmtRsOoBConsResourceModel @@ -155,7 +254,13 @@ func (r *MgmtRsOoBConsResource) Create(ctx context.Context, req resource.CreateR tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_relation_to_consumed_out_of_band_contract with id '%s'", data.Id.ValueString())) - jsonPayload := getMgmtRsOoBConsCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtRsOoBConsResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagMgmtRsOoBConsResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getMgmtRsOoBConsCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -202,9 +307,11 @@ func (r *MgmtRsOoBConsResource) Read(ctx context.Context, req resource.ReadReque func (r *MgmtRsOoBConsResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_relation_to_consumed_out_of_band_contract") var data *MgmtRsOoBConsResourceModel + var stateData *MgmtRsOoBConsResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -212,7 +319,13 @@ func (r *MgmtRsOoBConsResource) Update(ctx context.Context, req resource.UpdateR tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_relation_to_consumed_out_of_band_contract with id '%s'", data.Id.ValueString())) - jsonPayload := getMgmtRsOoBConsCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtRsOoBConsResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagMgmtRsOoBConsResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getMgmtRsOoBConsCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -266,7 +379,7 @@ func (r *MgmtRsOoBConsResource) ImportState(ctx context.Context, req resource.Im } func getAndSetMgmtRsOoBConsAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *MgmtRsOoBConsResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "mgmtRsOoBCons,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -299,6 +412,47 @@ func getAndSetMgmtRsOoBConsAttributes(ctx context.Context, diags *diag.Diagnosti if data.TnVzOOBBrCPName.IsUnknown() { data.TnVzOOBBrCPName = types.StringNull() } + TagAnnotationMgmtRsOoBCons := TagAnnotationMgmtRsOoBConsResourceModel{} + TagAnnotationMgmtRsOoBConsList := make([]TagAnnotationMgmtRsOoBConsResourceModel, 0) + TagTagMgmtRsOoBCons := TagTagMgmtRsOoBConsResourceModel{} + TagTagMgmtRsOoBConsList := make([]TagTagMgmtRsOoBConsResourceModel, 0) + _, ok := classReadInfo[0].(map[string]interface{})["children"] + if ok { + children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) + for _, child := range children { + for childClassName, childClassDetails := range child.(map[string]interface{}) { + childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) + if childClassName == "tagAnnotation" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagAnnotationMgmtRsOoBCons.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationMgmtRsOoBCons.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagAnnotationMgmtRsOoBConsList = append(TagAnnotationMgmtRsOoBConsList, TagAnnotationMgmtRsOoBCons) + } + if childClassName == "tagTag" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagTagMgmtRsOoBCons.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagMgmtRsOoBCons.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagTagMgmtRsOoBConsList = append(TagTagMgmtRsOoBConsList, TagTagMgmtRsOoBCons) + } + } + } + } + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationMgmtRsOoBConsList) + data.TagAnnotation = tagAnnotationSet + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagMgmtRsOoBConsList) + data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -341,9 +495,102 @@ func setMgmtRsOoBConsId(ctx context.Context, data *MgmtRsOoBConsResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getMgmtRsOoBConsCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel) *container.Container { +func getMgmtRsOoBConsTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagAnnotationMgmtRsOoBConsPlan, tagAnnotationMgmtRsOoBConsState []TagAnnotationMgmtRsOoBConsResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationMgmtRsOoBCons := range tagAnnotationMgmtRsOoBConsPlan { + childMap := NewAciObject() + if !tagAnnotationMgmtRsOoBCons.Key.IsNull() && !tagAnnotationMgmtRsOoBCons.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationMgmtRsOoBCons.Key.ValueString() + } + if !tagAnnotationMgmtRsOoBCons.Value.IsNull() && !tagAnnotationMgmtRsOoBCons.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationMgmtRsOoBCons.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationMgmtRsOoBCons.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotation := range tagAnnotationMgmtRsOoBConsState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotation.Key { + delete = false + break + } + } + if delete { + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) + } + } + } else { + data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) + } + + return childPayloads +} + +func getMgmtRsOoBConsTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagTagMgmtRsOoBConsPlan, tagTagMgmtRsOoBConsState []TagTagMgmtRsOoBConsResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagMgmtRsOoBCons := range tagTagMgmtRsOoBConsPlan { + childMap := NewAciObject() + if !tagTagMgmtRsOoBCons.Key.IsNull() && !tagTagMgmtRsOoBCons.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagMgmtRsOoBCons.Key.ValueString() + } + if !tagTagMgmtRsOoBCons.Value.IsNull() && !tagTagMgmtRsOoBCons.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagMgmtRsOoBCons.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagMgmtRsOoBCons.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTag := range tagTagMgmtRsOoBConsState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTag.Key { + delete = false + break + } + } + if delete { + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) + } + } + } else { + data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) + } + + return childPayloads +} + +func getMgmtRsOoBConsCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *MgmtRsOoBConsResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMgmtRsOoBConsResourceModel, tagTagPlan, tagTagState []TagTagMgmtRsOoBConsResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} + childPayloads := []map[string]interface{}{} + + TagAnnotationchildPayloads := getMgmtRsOoBConsTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) + if TagAnnotationchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + + TagTagchildPayloads := getMgmtRsOoBConsTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) + if TagTagchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagTagchildPayloads...) + + payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract_test.go b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract_test.go index 98bbe27b8..14bf7e258 100644 --- a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract_test.go +++ b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract_test.go @@ -65,6 +65,82 @@ func TestAccResourceMgmtRsOoBConsWithMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "priority", "unspecified"), ), }, + // Update with children + { + Config: testConfigMgmtRsOoBConsChildrenDependencyWithMgmtInstP, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "out_of_band_contract_name", "test_tn_vz_oob_br_cp_name"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "priority", "unspecified"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.1.value", "value_2"), + ), + }, + // Import testing with children + { + ResourceName: "aci_relation_to_consumed_out_of_band_contract.test", + ImportState: true, + ImportStateVerify: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "out_of_band_contract_name", "test_tn_vz_oob_br_cp_name"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "priority", "unspecified"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.1.value", "value_2"), + ), + }, + // Update with children removed from config + { + Config: testConfigMgmtRsOoBConsChildrenRemoveFromConfigDependencyWithMgmtInstP, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.#", "2"), + ), + }, + // Update with children first child removed + { + Config: testConfigMgmtRsOoBConsChildrenRemoveOneDependencyWithMgmtInstP, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.#", "1"), + ), + }, + // Update with all children removed + { + Config: testConfigMgmtRsOoBConsChildrenRemoveAllDependencyWithMgmtInstP, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.#", "0"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.#", "0"), + ), + }, }, }) } @@ -93,3 +169,64 @@ resource "aci_relation_to_consumed_out_of_band_contract" "test" { priority = "unspecified" } ` +const testConfigMgmtRsOoBConsChildrenDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` +resource "aci_relation_to_consumed_out_of_band_contract" "test" { + parent_dn = aci_external_management_network_instance_profile.test.id + out_of_band_contract_name = "test_tn_vz_oob_br_cp_name" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigMgmtRsOoBConsChildrenRemoveFromConfigDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` +resource "aci_relation_to_consumed_out_of_band_contract" "test" { + parent_dn = aci_external_management_network_instance_profile.test.id + out_of_band_contract_name = "test_tn_vz_oob_br_cp_name" +} +` + +const testConfigMgmtRsOoBConsChildrenRemoveOneDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` +resource "aci_relation_to_consumed_out_of_band_contract" "test" { + parent_dn = aci_external_management_network_instance_profile.test.id + out_of_band_contract_name = "test_tn_vz_oob_br_cp_name" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigMgmtRsOoBConsChildrenRemoveAllDependencyWithMgmtInstP = testConfigMgmtInstPMin + ` +resource "aci_relation_to_consumed_out_of_band_contract" "test" { + parent_dn = aci_external_management_network_instance_profile.test.id + out_of_band_contract_name = "test_tn_vz_oob_br_cp_name" + annotations = [] + tags = [] +} +` diff --git a/internal/provider/resource_aci_relation_to_fallback_route_group.go b/internal/provider/resource_aci_relation_to_fallback_route_group.go index 366bbb7f1..d848d6034 100644 --- a/internal/provider/resource_aci_relation_to_fallback_route_group.go +++ b/internal/provider/resource_aci_relation_to_fallback_route_group.go @@ -13,11 +13,13 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" @@ -40,10 +42,46 @@ type L3extRsOutToFBRGroupResource struct { // L3extRsOutToFBRGroupResourceModel describes the resource data model. type L3extRsOutToFBRGroupResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - TDn types.String `tfsdk:"target_dn"` + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + TDn types.String `tfsdk:"target_dn"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` +} + +// TagAnnotationL3extRsOutToFBRGroupResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationL3extRsOutToFBRGroupResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationL3extRsOutToFBRGroupResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationL3extRsOutToFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationL3extRsOutToFBRGroupResourceModelAttributeTypes()) +} + +// TagTagL3extRsOutToFBRGroupResourceModel describes the resource data model for the children without relation ships. +type TagTagL3extRsOutToFBRGroupResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagL3extRsOutToFBRGroupResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagL3extRsOutToFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagL3extRsOutToFBRGroupResourceModelAttributeTypes()) } type L3extRsOutToFBRGroupIdentifier struct { @@ -97,6 +135,62 @@ func (r *L3extRsOutToFBRGroupResource) Schema(ctx context.Context, req resource. }, MarkdownDescription: `The distinguished name of the VRF Fallback Route Group object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of resource: aci_relation_to_fallback_route_group") @@ -126,6 +220,11 @@ func (r *L3extRsOutToFBRGroupResource) Configure(ctx context.Context, req resour func (r *L3extRsOutToFBRGroupResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_relation_to_fallback_route_group") + // On create retrieve information on current state prior to making any changes in order to determine child delete operations + var stateData *L3extRsOutToFBRGroupResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) + setL3extRsOutToFBRGroupId(ctx, stateData) + getAndSetL3extRsOutToFBRGroupAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *L3extRsOutToFBRGroupResourceModel @@ -140,7 +239,13 @@ func (r *L3extRsOutToFBRGroupResource) Create(ctx context.Context, req resource. tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_relation_to_fallback_route_group with id '%s'", data.Id.ValueString())) - jsonPayload := getL3extRsOutToFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsOutToFBRGroupResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagL3extRsOutToFBRGroupResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getL3extRsOutToFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -187,9 +292,11 @@ func (r *L3extRsOutToFBRGroupResource) Read(ctx context.Context, req resource.Re func (r *L3extRsOutToFBRGroupResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_relation_to_fallback_route_group") var data *L3extRsOutToFBRGroupResourceModel + var stateData *L3extRsOutToFBRGroupResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -197,7 +304,13 @@ func (r *L3extRsOutToFBRGroupResource) Update(ctx context.Context, req resource. tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_relation_to_fallback_route_group with id '%s'", data.Id.ValueString())) - jsonPayload := getL3extRsOutToFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsOutToFBRGroupResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagL3extRsOutToFBRGroupResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getL3extRsOutToFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -251,7 +364,7 @@ func (r *L3extRsOutToFBRGroupResource) ImportState(ctx context.Context, req reso } func getAndSetL3extRsOutToFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *L3extRsOutToFBRGroupResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "l3extRsOutToFBRGroup,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -278,6 +391,47 @@ func getAndSetL3extRsOutToFBRGroupAttributes(ctx context.Context, diags *diag.Di if data.TDn.IsUnknown() { data.TDn = types.StringNull() } + TagAnnotationL3extRsOutToFBRGroup := TagAnnotationL3extRsOutToFBRGroupResourceModel{} + TagAnnotationL3extRsOutToFBRGroupList := make([]TagAnnotationL3extRsOutToFBRGroupResourceModel, 0) + TagTagL3extRsOutToFBRGroup := TagTagL3extRsOutToFBRGroupResourceModel{} + TagTagL3extRsOutToFBRGroupList := make([]TagTagL3extRsOutToFBRGroupResourceModel, 0) + _, ok := classReadInfo[0].(map[string]interface{})["children"] + if ok { + children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) + for _, child := range children { + for childClassName, childClassDetails := range child.(map[string]interface{}) { + childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) + if childClassName == "tagAnnotation" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagAnnotationL3extRsOutToFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationL3extRsOutToFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagAnnotationL3extRsOutToFBRGroupList = append(TagAnnotationL3extRsOutToFBRGroupList, TagAnnotationL3extRsOutToFBRGroup) + } + if childClassName == "tagTag" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagTagL3extRsOutToFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagL3extRsOutToFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagTagL3extRsOutToFBRGroupList = append(TagTagL3extRsOutToFBRGroupList, TagTagL3extRsOutToFBRGroup) + } + } + } + } + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationL3extRsOutToFBRGroupList) + data.TagAnnotation = tagAnnotationSet + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagL3extRsOutToFBRGroupList) + data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -320,9 +474,102 @@ func setL3extRsOutToFBRGroupId(ctx context.Context, data *L3extRsOutToFBRGroupRe data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getL3extRsOutToFBRGroupCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *L3extRsOutToFBRGroupResourceModel) *container.Container { +func getL3extRsOutToFBRGroupTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsOutToFBRGroupResourceModel, tagAnnotationL3extRsOutToFBRGroupPlan, tagAnnotationL3extRsOutToFBRGroupState []TagAnnotationL3extRsOutToFBRGroupResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationL3extRsOutToFBRGroup := range tagAnnotationL3extRsOutToFBRGroupPlan { + childMap := NewAciObject() + if !tagAnnotationL3extRsOutToFBRGroup.Key.IsNull() && !tagAnnotationL3extRsOutToFBRGroup.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationL3extRsOutToFBRGroup.Key.ValueString() + } + if !tagAnnotationL3extRsOutToFBRGroup.Value.IsNull() && !tagAnnotationL3extRsOutToFBRGroup.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationL3extRsOutToFBRGroup.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationL3extRsOutToFBRGroup.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotation := range tagAnnotationL3extRsOutToFBRGroupState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotation.Key { + delete = false + break + } + } + if delete { + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) + } + } + } else { + data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) + } + + return childPayloads +} + +func getL3extRsOutToFBRGroupTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extRsOutToFBRGroupResourceModel, tagTagL3extRsOutToFBRGroupPlan, tagTagL3extRsOutToFBRGroupState []TagTagL3extRsOutToFBRGroupResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagL3extRsOutToFBRGroup := range tagTagL3extRsOutToFBRGroupPlan { + childMap := NewAciObject() + if !tagTagL3extRsOutToFBRGroup.Key.IsNull() && !tagTagL3extRsOutToFBRGroup.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagL3extRsOutToFBRGroup.Key.ValueString() + } + if !tagTagL3extRsOutToFBRGroup.Value.IsNull() && !tagTagL3extRsOutToFBRGroup.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagL3extRsOutToFBRGroup.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagL3extRsOutToFBRGroup.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTag := range tagTagL3extRsOutToFBRGroupState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTag.Key { + delete = false + break + } + } + if delete { + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) + } + } + } else { + data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) + } + + return childPayloads +} + +func getL3extRsOutToFBRGroupCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *L3extRsOutToFBRGroupResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extRsOutToFBRGroupResourceModel, tagTagPlan, tagTagState []TagTagL3extRsOutToFBRGroupResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} + childPayloads := []map[string]interface{}{} + + TagAnnotationchildPayloads := getL3extRsOutToFBRGroupTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) + if TagAnnotationchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + + TagTagchildPayloads := getL3extRsOutToFBRGroupTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) + if TagTagchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagTagchildPayloads...) + + payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_relation_to_fallback_route_group_test.go b/internal/provider/resource_aci_relation_to_fallback_route_group_test.go index cdb9e31a1..6d59993bf 100644 --- a/internal/provider/resource_aci_relation_to_fallback_route_group_test.go +++ b/internal/provider/resource_aci_relation_to_fallback_route_group_test.go @@ -61,6 +61,80 @@ func TestAccResourceL3extRsOutToFBRGroupWithL3extOut(t *testing.T) { resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotation", "orchestrator:terraform"), ), }, + // Update with children + { + Config: testConfigL3extRsOutToFBRGroupChildrenDependencyWithL3extOut, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "target_dn", "uni/tn-test_tenant/ctx-test_vrf/fbrg-fallback_route_group"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.1.value", "value_2"), + ), + }, + // Import testing with children + { + ResourceName: "aci_relation_to_fallback_route_group.test", + ImportState: true, + ImportStateVerify: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "target_dn", "uni/tn-test_tenant/ctx-test_vrf/fbrg-fallback_route_group"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.1.value", "value_2"), + ), + }, + // Update with children removed from config + { + Config: testConfigL3extRsOutToFBRGroupChildrenRemoveFromConfigDependencyWithL3extOut, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.#", "2"), + ), + }, + // Update with children first child removed + { + Config: testConfigL3extRsOutToFBRGroupChildrenRemoveOneDependencyWithL3extOut, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.#", "1"), + ), + }, + // Update with all children removed + { + Config: testConfigL3extRsOutToFBRGroupChildrenRemoveAllDependencyWithL3extOut, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.#", "0"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.#", "0"), + ), + }, }, }) } @@ -94,3 +168,64 @@ resource "aci_relation_to_fallback_route_group" "test" { annotation = "orchestrator:terraform" } ` +const testConfigL3extRsOutToFBRGroupChildrenDependencyWithL3extOut = testConfigfvFBRGroupMinDependencyWithFvCtx + testConfigL3extOutMinDependencyWithFvTenant + ` +resource "aci_relation_to_fallback_route_group" "test" { + parent_dn = aci_l3_outside.test.id + target_dn = aci_vrf_fallback_route_group.test.id + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigL3extRsOutToFBRGroupChildrenRemoveFromConfigDependencyWithL3extOut = testConfigfvFBRGroupMinDependencyWithFvCtx + testConfigL3extOutMinDependencyWithFvTenant + ` +resource "aci_relation_to_fallback_route_group" "test" { + parent_dn = aci_l3_outside.test.id + target_dn = aci_vrf_fallback_route_group.test.id +} +` + +const testConfigL3extRsOutToFBRGroupChildrenRemoveOneDependencyWithL3extOut = testConfigfvFBRGroupMinDependencyWithFvCtx + testConfigL3extOutMinDependencyWithFvTenant + ` +resource "aci_relation_to_fallback_route_group" "test" { + parent_dn = aci_l3_outside.test.id + target_dn = aci_vrf_fallback_route_group.test.id + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigL3extRsOutToFBRGroupChildrenRemoveAllDependencyWithL3extOut = testConfigfvFBRGroupMinDependencyWithFvCtx + testConfigL3extOutMinDependencyWithFvTenant + ` +resource "aci_relation_to_fallback_route_group" "test" { + parent_dn = aci_l3_outside.test.id + target_dn = aci_vrf_fallback_route_group.test.id + annotations = [] + tags = [] +} +` diff --git a/internal/provider/resource_aci_vrf_fallback_route_group.go b/internal/provider/resource_aci_vrf_fallback_route_group.go index f7e5737fd..8466623bd 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group.go @@ -42,22 +42,26 @@ type FvFBRGroupResource struct { // FvFBRGroupResourceModel describes the resource data model. type FvFBRGroupResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - FvFBRMember types.Set `tfsdk:"vrf_fallback_route_group_members"` + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + FvFBRMember types.Set `tfsdk:"vrf_fallback_route_group_members"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` } // FvFBRMemberFvFBRGroupResourceModel describes the resource data model for the children without relation ships. type FvFBRMemberFvFBRGroupResourceModel struct { - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - RnhAddr types.String `tfsdk:"fallback_member"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + RnhAddr types.String `tfsdk:"fallback_member"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` } func FvFBRMemberFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { @@ -67,6 +71,8 @@ func FvFBRMemberFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { "name": types.StringType, "name_alias": types.StringType, "fallback_member": types.StringType, + "annotations": types.SetType{ElemType: TagAnnotationFvFBRMemberFvFBRGroupResourceModelElementType()}, + "tags": types.SetType{ElemType: TagTagFvFBRMemberFvFBRGroupResourceModelElementType()}, } } @@ -74,6 +80,74 @@ func FvFBRMemberFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, FvFBRMemberFvFBRGroupResourceModelAttributeTypes()) } +// TagAnnotationFvFBRMemberFvFBRGroupResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationFvFBRMemberFvFBRGroupResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationFvFBRMemberFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationFvFBRMemberFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvFBRMemberFvFBRGroupResourceModelAttributeTypes()) +} + +// TagTagFvFBRMemberFvFBRGroupResourceModel describes the resource data model for the children without relation ships. +type TagTagFvFBRMemberFvFBRGroupResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagFvFBRMemberFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagFvFBRMemberFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvFBRMemberFvFBRGroupResourceModelAttributeTypes()) +} + +// TagAnnotationFvFBRGroupResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationFvFBRGroupResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvFBRGroupResourceModelAttributeTypes()) +} + +// TagTagFvFBRGroupResourceModel describes the resource data model for the children without relation ships. +type TagTagFvFBRGroupResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagFvFBRGroupResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagFvFBRGroupResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvFBRGroupResourceModelAttributeTypes()) +} + type FvFBRGroupIdentifier struct { Name types.String } @@ -196,6 +270,118 @@ func (r *FvFBRGroupResource) Schema(ctx context.Context, req resource.SchemaRequ }, MarkdownDescription: `The address of the VRF Fallback Route Group Member object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + }, + }, + }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, }, }, }, @@ -250,7 +436,13 @@ func (r *FvFBRGroupResource) Create(ctx context.Context, req resource.CreateRequ var fvFBRMemberPlan, fvFBRMemberState []FvFBRMemberFvFBRGroupResourceModel data.FvFBRMember.ElementsAs(ctx, &fvFBRMemberPlan, false) stateData.FvFBRMember.ElementsAs(ctx, &fvFBRMemberState, false) - jsonPayload := getFvFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data, fvFBRMemberPlan, fvFBRMemberState) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvFBRGroupResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagFvFBRGroupResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getFvFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data, fvFBRMemberPlan, fvFBRMemberState, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -312,7 +504,13 @@ func (r *FvFBRGroupResource) Update(ctx context.Context, req resource.UpdateRequ var fvFBRMemberPlan, fvFBRMemberState []FvFBRMemberFvFBRGroupResourceModel data.FvFBRMember.ElementsAs(ctx, &fvFBRMemberPlan, false) stateData.FvFBRMember.ElementsAs(ctx, &fvFBRMemberState, false) - jsonPayload := getFvFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data, fvFBRMemberPlan, fvFBRMemberState) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvFBRGroupResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagFvFBRGroupResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getFvFBRGroupCreateJsonPayload(ctx, &resp.Diagnostics, data, fvFBRMemberPlan, fvFBRMemberState, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -366,7 +564,7 @@ func (r *FvFBRGroupResource) ImportState(ctx context.Context, req resource.Impor } func getAndSetFvFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *FvFBRGroupResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "fvFBRGroup,fvFBRMember"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "fvFBRGroup,fvFBRMember,tagAnnotation,tagTag,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -407,6 +605,14 @@ func getAndSetFvFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, } FvFBRMemberFvFBRGroup := FvFBRMemberFvFBRGroupResourceModel{} FvFBRMemberFvFBRGroupList := make([]FvFBRMemberFvFBRGroupResourceModel, 0) + TagAnnotationFvFBRMemberFvFBRGroup := TagAnnotationFvFBRMemberFvFBRGroupResourceModel{} + TagAnnotationFvFBRMemberFvFBRGroupList := make([]TagAnnotationFvFBRMemberFvFBRGroupResourceModel, 0) + TagTagFvFBRMemberFvFBRGroup := TagTagFvFBRMemberFvFBRGroupResourceModel{} + TagTagFvFBRMemberFvFBRGroupList := make([]TagTagFvFBRMemberFvFBRGroupResourceModel, 0) + TagAnnotationFvFBRGroup := TagAnnotationFvFBRGroupResourceModel{} + TagAnnotationFvFBRGroupList := make([]TagAnnotationFvFBRGroupResourceModel, 0) + TagTagFvFBRGroup := TagTagFvFBRGroupResourceModel{} + TagTagFvFBRGroupList := make([]TagTagFvFBRGroupResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) @@ -432,13 +638,76 @@ func getAndSetFvFBRGroupAttributes(ctx context.Context, diags *diag.Diagnostics, } } + childrenOfFvFBRMemberFvFBRGroup, childrenOfFvFBRMemberFvFBRGroupExist := childClassDetails.(map[string]interface{})["children"] + if childrenOfFvFBRMemberFvFBRGroupExist { + for _, childFvFBRMemberFvFBRGroup := range childrenOfFvFBRMemberFvFBRGroup.([]interface{}) { + for childClassNameFvFBRMemberFvFBRGroup, childClassDetailsFvFBRMemberFvFBRGroup := range childFvFBRMemberFvFBRGroup.(map[string]interface{}) { + if childClassNameFvFBRMemberFvFBRGroup == "tagAnnotation" { + tagAnnotationchildAttributeValue := childClassDetailsFvFBRMemberFvFBRGroup.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { + if childAttributeName == "key" { + TagAnnotationFvFBRMemberFvFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationFvFBRMemberFvFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagAnnotationFvFBRMemberFvFBRGroupList = append(TagAnnotationFvFBRMemberFvFBRGroupList, TagAnnotationFvFBRMemberFvFBRGroup) + } + if childClassNameFvFBRMemberFvFBRGroup == "tagTag" { + tagTagchildAttributeValue := childClassDetailsFvFBRMemberFvFBRGroup.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { + if childAttributeName == "key" { + TagTagFvFBRMemberFvFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagFvFBRMemberFvFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagTagFvFBRMemberFvFBRGroupList = append(TagTagFvFBRMemberFvFBRGroupList, TagTagFvFBRMemberFvFBRGroup) + } + } + } + } + TagAnnotationFvFBRMemberFvFBRGroupSet, _ := types.SetValueFrom(ctx, TagAnnotationFvFBRMemberFvFBRGroupResourceModelElementType(), TagAnnotationFvFBRMemberFvFBRGroupList) + FvFBRMemberFvFBRGroup.TagAnnotation = TagAnnotationFvFBRMemberFvFBRGroupSet + TagTagFvFBRMemberFvFBRGroupSet, _ := types.SetValueFrom(ctx, TagTagFvFBRMemberFvFBRGroupResourceModelElementType(), TagTagFvFBRMemberFvFBRGroupList) + FvFBRMemberFvFBRGroup.TagTag = TagTagFvFBRMemberFvFBRGroupSet FvFBRMemberFvFBRGroupList = append(FvFBRMemberFvFBRGroupList, FvFBRMemberFvFBRGroup) } + if childClassName == "tagAnnotation" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagAnnotationFvFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationFvFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagAnnotationFvFBRGroupList = append(TagAnnotationFvFBRGroupList, TagAnnotationFvFBRGroup) + } + if childClassName == "tagTag" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagTagFvFBRGroup.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagFvFBRGroup.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagTagFvFBRGroupList = append(TagTagFvFBRGroupList, TagTagFvFBRGroup) + } } } } fvFBRMemberSet, _ := types.SetValueFrom(ctx, data.FvFBRMember.ElementType(ctx), FvFBRMemberFvFBRGroupList) data.FvFBRMember = fvFBRMemberSet + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationFvFBRGroupList) + data.TagAnnotation = tagAnnotationSet + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagFvFBRGroupList) + data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -483,6 +752,7 @@ func setFvFBRGroupId(ctx context.Context, data *FvFBRGroupResourceModel) { func getFvFBRGroupFvFBRMemberChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, fvFBRMemberFvFBRGroupPlan, fvFBRMemberFvFBRGroupState []FvFBRMemberFvFBRGroupResourceModel) []map[string]interface{} { childPayloads := []map[string]interface{}{} + FvFBRMemberFvFBRGroupChildren := make([]map[string]interface{}, 0) if !data.FvFBRMember.IsNull() && !data.FvFBRMember.IsUnknown() { fvFBRMemberIdentifiers := []FvFBRMemberIdentifier{} for _, fvFBRMemberFvFBRGroup := range fvFBRMemberFvFBRGroupPlan { @@ -504,6 +774,81 @@ func getFvFBRGroupFvFBRMemberChildPayloads(ctx context.Context, diags *diag.Diag if !fvFBRMemberFvFBRGroup.RnhAddr.IsNull() && !fvFBRMemberFvFBRGroup.RnhAddr.IsUnknown() { childMap.Attributes["rnhAddr"] = fvFBRMemberFvFBRGroup.RnhAddr.ValueString() } + + var tagAnnotationFvFBRMemberFvFBRGroupPlan, tagAnnotationFvFBRMemberFvFBRGroupState []TagAnnotationFvFBRMemberFvFBRGroupResourceModel + fvFBRMemberFvFBRGroup.TagAnnotation.ElementsAs(ctx, &tagAnnotationFvFBRMemberFvFBRGroupPlan, false) + for _, tagAnnotationFvFBRMemberFvFBRGroupstate := range fvFBRMemberFvFBRGroupState { + tagAnnotationFvFBRMemberFvFBRGroupstate.TagAnnotation.ElementsAs(ctx, &tagAnnotationFvFBRMemberFvFBRGroupState, false) + } + if !fvFBRMemberFvFBRGroup.TagAnnotation.IsNull() && !fvFBRMemberFvFBRGroup.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationFvFBRMemberFvFBRGroup := range tagAnnotationFvFBRMemberFvFBRGroupPlan { + tagAnnotationFvFBRMemberFvFBRGroupChildMap := NewAciObject() + if !tagAnnotationFvFBRMemberFvFBRGroup.Key.IsNull() && !tagAnnotationFvFBRMemberFvFBRGroup.Key.IsUnknown() { + tagAnnotationFvFBRMemberFvFBRGroupChildMap.Attributes["key"] = tagAnnotationFvFBRMemberFvFBRGroup.Key.ValueString() + } + if !tagAnnotationFvFBRMemberFvFBRGroup.Value.IsNull() && !tagAnnotationFvFBRMemberFvFBRGroup.Value.IsUnknown() { + tagAnnotationFvFBRMemberFvFBRGroupChildMap.Attributes["value"] = tagAnnotationFvFBRMemberFvFBRGroup.Value.ValueString() + } + FvFBRMemberFvFBRGroupChildren = append(FvFBRMemberFvFBRGroupChildren, map[string]interface{}{"tagAnnotation": tagAnnotationFvFBRMemberFvFBRGroupChildMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationFvFBRMemberFvFBRGroup.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotationFvFBRMemberFvFBRGroup := range tagAnnotationFvFBRMemberFvFBRGroupState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotationFvFBRMemberFvFBRGroup.Key { + delete = false + break + } + } + if delete { + tagAnnotationFvFBRMemberFvFBRGroupChildMapForDelete := NewAciObject() + tagAnnotationFvFBRMemberFvFBRGroupChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationFvFBRMemberFvFBRGroupChildMapForDelete.Attributes["key"] = tagAnnotationFvFBRMemberFvFBRGroup.Key.ValueString() + FvFBRMemberFvFBRGroupChildren = append(FvFBRMemberFvFBRGroupChildren, map[string]interface{}{"tagAnnotation": tagAnnotationFvFBRMemberFvFBRGroupChildMapForDelete}) + } + } + } + + var tagTagFvFBRMemberFvFBRGroupPlan, tagTagFvFBRMemberFvFBRGroupState []TagTagFvFBRMemberFvFBRGroupResourceModel + fvFBRMemberFvFBRGroup.TagTag.ElementsAs(ctx, &tagTagFvFBRMemberFvFBRGroupPlan, false) + for _, tagTagFvFBRMemberFvFBRGroupstate := range fvFBRMemberFvFBRGroupState { + tagTagFvFBRMemberFvFBRGroupstate.TagTag.ElementsAs(ctx, &tagTagFvFBRMemberFvFBRGroupState, false) + } + if !fvFBRMemberFvFBRGroup.TagTag.IsNull() && !fvFBRMemberFvFBRGroup.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagFvFBRMemberFvFBRGroup := range tagTagFvFBRMemberFvFBRGroupPlan { + tagTagFvFBRMemberFvFBRGroupChildMap := NewAciObject() + if !tagTagFvFBRMemberFvFBRGroup.Key.IsNull() && !tagTagFvFBRMemberFvFBRGroup.Key.IsUnknown() { + tagTagFvFBRMemberFvFBRGroupChildMap.Attributes["key"] = tagTagFvFBRMemberFvFBRGroup.Key.ValueString() + } + if !tagTagFvFBRMemberFvFBRGroup.Value.IsNull() && !tagTagFvFBRMemberFvFBRGroup.Value.IsUnknown() { + tagTagFvFBRMemberFvFBRGroupChildMap.Attributes["value"] = tagTagFvFBRMemberFvFBRGroup.Value.ValueString() + } + FvFBRMemberFvFBRGroupChildren = append(FvFBRMemberFvFBRGroupChildren, map[string]interface{}{"tagTag": tagTagFvFBRMemberFvFBRGroupChildMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagFvFBRMemberFvFBRGroup.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTagFvFBRMemberFvFBRGroup := range tagTagFvFBRMemberFvFBRGroupState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTagFvFBRMemberFvFBRGroup.Key { + delete = false + break + } + } + if delete { + tagTagFvFBRMemberFvFBRGroupChildMapForDelete := NewAciObject() + tagTagFvFBRMemberFvFBRGroupChildMapForDelete.Attributes["status"] = "deleted" + tagTagFvFBRMemberFvFBRGroupChildMapForDelete.Attributes["key"] = tagTagFvFBRMemberFvFBRGroup.Key.ValueString() + FvFBRMemberFvFBRGroupChildren = append(FvFBRMemberFvFBRGroupChildren, map[string]interface{}{"tagTag": tagTagFvFBRMemberFvFBRGroupChildMapForDelete}) + } + } + } + childMap.Children = FvFBRMemberFvFBRGroupChildren childPayloads = append(childPayloads, map[string]interface{}{"fvFBRMember": childMap}) fvFBRMemberIdentifier := FvFBRMemberIdentifier{} fvFBRMemberIdentifier.RnhAddr = fvFBRMemberFvFBRGroup.RnhAddr @@ -531,7 +876,85 @@ func getFvFBRGroupFvFBRMemberChildPayloads(ctx context.Context, diags *diag.Diag return childPayloads } -func getFvFBRGroupCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, fvFBRMemberPlan, fvFBRMemberState []FvFBRMemberFvFBRGroupResourceModel) *container.Container { +func getFvFBRGroupTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, tagAnnotationFvFBRGroupPlan, tagAnnotationFvFBRGroupState []TagAnnotationFvFBRGroupResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationFvFBRGroup := range tagAnnotationFvFBRGroupPlan { + childMap := NewAciObject() + if !tagAnnotationFvFBRGroup.Key.IsNull() && !tagAnnotationFvFBRGroup.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationFvFBRGroup.Key.ValueString() + } + if !tagAnnotationFvFBRGroup.Value.IsNull() && !tagAnnotationFvFBRGroup.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationFvFBRGroup.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationFvFBRGroup.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotation := range tagAnnotationFvFBRGroupState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotation.Key { + delete = false + break + } + } + if delete { + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) + } + } + } else { + data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) + } + + return childPayloads +} + +func getFvFBRGroupTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, tagTagFvFBRGroupPlan, tagTagFvFBRGroupState []TagTagFvFBRGroupResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagFvFBRGroup := range tagTagFvFBRGroupPlan { + childMap := NewAciObject() + if !tagTagFvFBRGroup.Key.IsNull() && !tagTagFvFBRGroup.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagFvFBRGroup.Key.ValueString() + } + if !tagTagFvFBRGroup.Value.IsNull() && !tagTagFvFBRGroup.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagFvFBRGroup.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagFvFBRGroup.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTag := range tagTagFvFBRGroupState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTag.Key { + delete = false + break + } + } + if delete { + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) + } + } + } else { + data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) + } + + return childPayloads +} + +func getFvFBRGroupCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvFBRGroupResourceModel, fvFBRMemberPlan, fvFBRMemberState []FvFBRMemberFvFBRGroupResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvFBRGroupResourceModel, tagTagPlan, tagTagState []TagTagFvFBRGroupResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} childPayloads := []map[string]interface{}{} @@ -542,6 +965,18 @@ func getFvFBRGroupCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics } childPayloads = append(childPayloads, FvFBRMemberchildPayloads...) + TagAnnotationchildPayloads := getFvFBRGroupTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) + if TagAnnotationchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + + TagTagchildPayloads := getFvFBRGroupTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) + if TagTagchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagTagchildPayloads...) + payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() diff --git a/internal/provider/resource_aci_vrf_fallback_route_group_member.go b/internal/provider/resource_aci_vrf_fallback_route_group_member.go index ab471d4c3..8dd9d469b 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group_member.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group_member.go @@ -13,11 +13,13 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" @@ -40,13 +42,49 @@ type FvFBRMemberResource struct { // FvFBRMemberResourceModel describes the resource data model. type FvFBRMemberResourceModel struct { - Id types.String `tfsdk:"id"` - ParentDn types.String `tfsdk:"parent_dn"` - Annotation types.String `tfsdk:"annotation"` - Descr types.String `tfsdk:"description"` - Name types.String `tfsdk:"name"` - NameAlias types.String `tfsdk:"name_alias"` - RnhAddr types.String `tfsdk:"fallback_member"` + Id types.String `tfsdk:"id"` + ParentDn types.String `tfsdk:"parent_dn"` + Annotation types.String `tfsdk:"annotation"` + Descr types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + NameAlias types.String `tfsdk:"name_alias"` + RnhAddr types.String `tfsdk:"fallback_member"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` +} + +// TagAnnotationFvFBRMemberResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationFvFBRMemberResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationFvFBRMemberResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationFvFBRMemberResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationFvFBRMemberResourceModelAttributeTypes()) +} + +// TagTagFvFBRMemberResourceModel describes the resource data model for the children without relation ships. +type TagTagFvFBRMemberResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagFvFBRMemberResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagFvFBRMemberResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagFvFBRMemberResourceModelAttributeTypes()) } type FvFBRMemberIdentifier struct { @@ -127,6 +165,62 @@ func (r *FvFBRMemberResource) Schema(ctx context.Context, req resource.SchemaReq }, MarkdownDescription: `The address of the VRF Fallback Route Group Member object.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, } tflog.Debug(ctx, "End schema of resource: aci_vrf_fallback_route_group_member") @@ -156,6 +250,11 @@ func (r *FvFBRMemberResource) Configure(ctx context.Context, req resource.Config func (r *FvFBRMemberResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { tflog.Debug(ctx, "Start create of resource: aci_vrf_fallback_route_group_member") + // On create retrieve information on current state prior to making any changes in order to determine child delete operations + var stateData *FvFBRMemberResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &stateData)...) + setFvFBRMemberId(ctx, stateData) + getAndSetFvFBRMemberAttributes(ctx, &resp.Diagnostics, r.client, stateData) var data *FvFBRMemberResourceModel @@ -170,7 +269,13 @@ func (r *FvFBRMemberResource) Create(ctx context.Context, req resource.CreateReq tflog.Debug(ctx, fmt.Sprintf("Create of resource aci_vrf_fallback_route_group_member with id '%s'", data.Id.ValueString())) - jsonPayload := getFvFBRMemberCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvFBRMemberResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagFvFBRMemberResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getFvFBRMemberCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -217,9 +322,11 @@ func (r *FvFBRMemberResource) Read(ctx context.Context, req resource.ReadRequest func (r *FvFBRMemberResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { tflog.Debug(ctx, "Start update of resource: aci_vrf_fallback_route_group_member") var data *FvFBRMemberResourceModel + var stateData *FvFBRMemberResourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + resp.Diagnostics.Append(req.State.Get(ctx, &stateData)...) if resp.Diagnostics.HasError() { return @@ -227,7 +334,13 @@ func (r *FvFBRMemberResource) Update(ctx context.Context, req resource.UpdateReq tflog.Debug(ctx, fmt.Sprintf("Update of resource aci_vrf_fallback_route_group_member with id '%s'", data.Id.ValueString())) - jsonPayload := getFvFBRMemberCreateJsonPayload(ctx, &resp.Diagnostics, data) + var tagAnnotationPlan, tagAnnotationState []TagAnnotationFvFBRMemberResourceModel + data.TagAnnotation.ElementsAs(ctx, &tagAnnotationPlan, false) + stateData.TagAnnotation.ElementsAs(ctx, &tagAnnotationState, false) + var tagTagPlan, tagTagState []TagTagFvFBRMemberResourceModel + data.TagTag.ElementsAs(ctx, &tagTagPlan, false) + stateData.TagTag.ElementsAs(ctx, &tagTagState, false) + jsonPayload := getFvFBRMemberCreateJsonPayload(ctx, &resp.Diagnostics, data, tagAnnotationPlan, tagAnnotationState, tagTagPlan, tagTagState) if resp.Diagnostics.HasError() { return @@ -281,7 +394,7 @@ func (r *FvFBRMemberResource) ImportState(ctx context.Context, req resource.Impo } func getAndSetFvFBRMemberAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *FvFBRMemberResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json", data.Id.ValueString()), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "fvFBRMember,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -326,6 +439,47 @@ func getAndSetFvFBRMemberAttributes(ctx context.Context, diags *diag.Diagnostics if data.RnhAddr.IsUnknown() { data.RnhAddr = types.StringNull() } + TagAnnotationFvFBRMember := TagAnnotationFvFBRMemberResourceModel{} + TagAnnotationFvFBRMemberList := make([]TagAnnotationFvFBRMemberResourceModel, 0) + TagTagFvFBRMember := TagTagFvFBRMemberResourceModel{} + TagTagFvFBRMemberList := make([]TagTagFvFBRMemberResourceModel, 0) + _, ok := classReadInfo[0].(map[string]interface{})["children"] + if ok { + children := classReadInfo[0].(map[string]interface{})["children"].([]interface{}) + for _, child := range children { + for childClassName, childClassDetails := range child.(map[string]interface{}) { + childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) + if childClassName == "tagAnnotation" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagAnnotationFvFBRMember.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationFvFBRMember.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagAnnotationFvFBRMemberList = append(TagAnnotationFvFBRMemberList, TagAnnotationFvFBRMember) + } + if childClassName == "tagTag" { + for childAttributeName, childAttributeValue := range childAttributes { + if childAttributeName == "key" { + TagTagFvFBRMember.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagFvFBRMember.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + + } + TagTagFvFBRMemberList = append(TagTagFvFBRMemberList, TagTagFvFBRMember) + } + } + } + } + tagAnnotationSet, _ := types.SetValueFrom(ctx, data.TagAnnotation.ElementType(ctx), TagAnnotationFvFBRMemberList) + data.TagAnnotation = tagAnnotationSet + tagTagSet, _ := types.SetValueFrom(ctx, data.TagTag.ElementType(ctx), TagTagFvFBRMemberList) + data.TagTag = tagTagSet } else { diags.AddError( "too many results in response", @@ -368,9 +522,102 @@ func setFvFBRMemberId(ctx context.Context, data *FvFBRMemberResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getFvFBRMemberCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvFBRMemberResourceModel) *container.Container { +func getFvFBRMemberTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRMemberResourceModel, tagAnnotationFvFBRMemberPlan, tagAnnotationFvFBRMemberState []TagAnnotationFvFBRMemberResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationFvFBRMember := range tagAnnotationFvFBRMemberPlan { + childMap := NewAciObject() + if !tagAnnotationFvFBRMember.Key.IsNull() && !tagAnnotationFvFBRMember.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationFvFBRMember.Key.ValueString() + } + if !tagAnnotationFvFBRMember.Value.IsNull() && !tagAnnotationFvFBRMember.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationFvFBRMember.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationFvFBRMember.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotation := range tagAnnotationFvFBRMemberState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotation.Key { + delete = false + break + } + } + if delete { + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) + } + } + } else { + data.TagAnnotation = types.SetNull(data.TagAnnotation.ElementType(ctx)) + } + + return childPayloads +} + +func getFvFBRMemberTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *FvFBRMemberResourceModel, tagTagFvFBRMemberPlan, tagTagFvFBRMemberState []TagTagFvFBRMemberResourceModel) []map[string]interface{} { + childPayloads := []map[string]interface{}{} + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagFvFBRMember := range tagTagFvFBRMemberPlan { + childMap := NewAciObject() + if !tagTagFvFBRMember.Key.IsNull() && !tagTagFvFBRMember.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagFvFBRMember.Key.ValueString() + } + if !tagTagFvFBRMember.Value.IsNull() && !tagTagFvFBRMember.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagFvFBRMember.Value.ValueString() + } + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagFvFBRMember.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTag := range tagTagFvFBRMemberState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTag.Key { + delete = false + break + } + } + if delete { + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) + } + } + } else { + data.TagTag = types.SetNull(data.TagTag.ElementType(ctx)) + } + + return childPayloads +} + +func getFvFBRMemberCreateJsonPayload(ctx context.Context, diags *diag.Diagnostics, data *FvFBRMemberResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationFvFBRMemberResourceModel, tagTagPlan, tagTagState []TagTagFvFBRMemberResourceModel) *container.Container { payloadMap := map[string]interface{}{} payloadMap["attributes"] = map[string]string{} + childPayloads := []map[string]interface{}{} + + TagAnnotationchildPayloads := getFvFBRMemberTagAnnotationChildPayloads(ctx, diags, data, tagAnnotationPlan, tagAnnotationState) + if TagAnnotationchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagAnnotationchildPayloads...) + + TagTagchildPayloads := getFvFBRMemberTagTagChildPayloads(ctx, diags, data, tagTagPlan, tagTagState) + if TagTagchildPayloads == nil { + return nil + } + childPayloads = append(childPayloads, TagTagchildPayloads...) + + payloadMap["children"] = childPayloads if !data.Annotation.IsNull() && !data.Annotation.IsUnknown() { payloadMap["attributes"].(map[string]string)["annotation"] = data.Annotation.ValueString() } diff --git a/internal/provider/resource_aci_vrf_fallback_route_group_member_test.go b/internal/provider/resource_aci_vrf_fallback_route_group_member_test.go index be80ea36d..109e716b9 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group_member_test.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group_member_test.go @@ -73,6 +73,86 @@ func TestAccResourceFvFBRMemberWithFvFBRGroup(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "name_alias", ""), ), }, + // Update with children + { + Config: testConfigFvFBRMemberChildrenDependencyWithFvFBRGroup, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "fallback_member", "2.2.2.3"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "description", ""), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "name", ""), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.1.value", "value_2"), + ), + }, + // Import testing with children + { + ResourceName: "aci_vrf_fallback_route_group_member.test", + ImportState: true, + ImportStateVerify: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "fallback_member", "2.2.2.3"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotation", "orchestrator:terraform"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "description", ""), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "name", ""), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.1.value", "value_2"), + ), + }, + // Update with children removed from config + { + Config: testConfigFvFBRMemberChildrenRemoveFromConfigDependencyWithFvFBRGroup, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.#", "2"), + ), + }, + // Update with children first child removed + { + Config: testConfigFvFBRMemberChildrenRemoveOneDependencyWithFvFBRGroup, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.#", "1"), + ), + }, + // Update with all children removed + { + Config: testConfigFvFBRMemberChildrenRemoveAllDependencyWithFvFBRGroup, + ExpectNonEmptyPlan: false, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.#", "0"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.#", "0"), + ), + }, }, }) } @@ -105,3 +185,64 @@ resource "aci_vrf_fallback_route_group_member" "test" { name_alias = "" } ` +const testConfigFvFBRMemberChildrenDependencyWithFvFBRGroup = testConfigFvFBRGroupMinDependencyWithFvCtx + ` +resource "aci_vrf_fallback_route_group_member" "test" { + parent_dn = aci_vrf_fallback_route_group.test.id + fallback_member = "2.2.2.3" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigFvFBRMemberChildrenRemoveFromConfigDependencyWithFvFBRGroup = testConfigFvFBRGroupMinDependencyWithFvCtx + ` +resource "aci_vrf_fallback_route_group_member" "test" { + parent_dn = aci_vrf_fallback_route_group.test.id + fallback_member = "2.2.2.3" +} +` + +const testConfigFvFBRMemberChildrenRemoveOneDependencyWithFvFBRGroup = testConfigFvFBRGroupMinDependencyWithFvCtx + ` +resource "aci_vrf_fallback_route_group_member" "test" { + parent_dn = aci_vrf_fallback_route_group.test.id + fallback_member = "2.2.2.3" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] +} +` + +const testConfigFvFBRMemberChildrenRemoveAllDependencyWithFvFBRGroup = testConfigFvFBRGroupMinDependencyWithFvCtx + ` +resource "aci_vrf_fallback_route_group_member" "test" { + parent_dn = aci_vrf_fallback_route_group.test.id + fallback_member = "2.2.2.3" + annotations = [] + tags = [] +} +` diff --git a/internal/provider/resource_aci_vrf_fallback_route_group_test.go b/internal/provider/resource_aci_vrf_fallback_route_group_test.go index 466f47e45..9978f34be 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group_test.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group_test.go @@ -78,6 +78,14 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotation", "orchestrator:terraform"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "description", ""), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.1.value", "value_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.description", "description_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.fallback_member", "2.2.2.2"), @@ -100,6 +108,14 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotation", "orchestrator:terraform"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "description", ""), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "name_alias", ""), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.1.value", "value_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.description", "description_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.fallback_member", "2.2.2.2"), @@ -117,6 +133,16 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { Config: testConfigFvFBRGroupChildrenRemoveFromConfigDependencyWithFvCtx, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.#", "2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.key", "key_0"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.value", "value_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.1.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.1.value", "value_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.#", "2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.description", "description_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.fallback_member", "2.2.2.2"), @@ -135,6 +161,12 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { Config: testConfigFvFBRGroupChildrenRemoveOneDependencyWithFvCtx, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.key", "key_1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.value", "value_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.#", "1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.annotation", "annotation_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.description", "description_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.fallback_member", "2.2.2.3"), @@ -148,6 +180,8 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { Config: testConfigFvFBRGroupChildrenRemoveAllDependencyWithFvCtx, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.#", "0"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.#", "0"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.#", "0"), ), }, @@ -185,6 +219,26 @@ const testConfigFvFBRGroupChildrenDependencyWithFvCtx = testConfigFvCtxMinDepend resource "aci_vrf_fallback_route_group" "test" { parent_dn = aci_vrf.test.id name = "fallback_route_group" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] vrf_fallback_route_group_members = [ { annotation = "annotation_1" @@ -215,6 +269,18 @@ const testConfigFvFBRGroupChildrenRemoveOneDependencyWithFvCtx = testConfigFvCtx resource "aci_vrf_fallback_route_group" "test" { parent_dn = aci_vrf.test.id name = "fallback_route_group" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] vrf_fallback_route_group_members = [ { annotation = "annotation_2" @@ -231,6 +297,8 @@ const testConfigFvFBRGroupChildrenRemoveAllDependencyWithFvCtx = testConfigFvCtx resource "aci_vrf_fallback_route_group" "test" { parent_dn = aci_vrf.test.id name = "fallback_route_group" + annotations = [] + tags = [] vrf_fallback_route_group_members = [] } ` From 4b7c03d1c0141f03f47b7995a1a6380e89d00096 Mon Sep 17 00:00:00 2001 From: Shreyas Date: Tue, 14 May 2024 20:25:49 -0400 Subject: [PATCH 11/20] [ignore] Modified resource docs template to incorporate grandchildren using recursive templates --- docs/resources/annotation.md | 2 + docs/resources/communication_policy.md | 68 ++++++++++++-- docs/resources/endpoint_tag_ip.md | 6 +- docs/resources/endpoint_tag_mac.md | 6 +- ...nal_management_network_instance_profile.md | 24 +++-- .../external_management_network_subnet.md | 6 +- docs/resources/l3out_consumer_label.md | 6 +- docs/resources/l3out_redistribute_policy.md | 6 +- docs/resources/out_of_band_contract.md | 6 +- docs/resources/pim_route_map_entry.md | 6 +- docs/resources/pim_route_map_policy.md | 7 +- ...lation_to_consumed_out_of_band_contract.md | 6 +- .../relation_to_fallback_route_group.md | 6 +- docs/resources/tag.md | 2 + docs/resources/vrf_fallback_route_group.md | 23 ++++- .../vrf_fallback_route_group_member.md | 6 +- gen/generator.go | 46 ++++++++++ gen/templates/resource.md.tmpl | 90 +++++++++++-------- 18 files changed, 249 insertions(+), 73 deletions(-) diff --git a/docs/resources/annotation.md b/docs/resources/annotation.md index 127e6224d..1e55bcf29 100644 --- a/docs/resources/annotation.md +++ b/docs/resources/annotation.md @@ -113,3 +113,5 @@ import { to = aci_annotation.example_tenant } ``` + + diff --git a/docs/resources/communication_policy.md b/docs/resources/communication_policy.md index ed209d784..4d12771bc 100644 --- a/docs/resources/communication_policy.md +++ b/docs/resources/communication_policy.md @@ -121,9 +121,6 @@ All examples for the Communication Policy resource can be found in the [examples * `http_ssl_configuration` - (list) A list of Http Ssl Configuration (ACI object [commHttps](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commHttps/overview)). Http Ssl Configuration can also be configured using a separate [aci_](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/) resource. - #### Required #### - - #### Optional #### * `access_control_allow_credential` (accessControlAllowCredential) - (string) accessControlAllowCredential. @@ -177,15 +174,73 @@ All examples for the Communication Policy resource can be found in the [examples - Default: `enabled` - Valid Values: `disabled`, `enabled`. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + * `tp` - (list) A list of Tp (ACI object [commRsClientCertCA](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commRsClientCertCA/overview)) pointing to (ACI Object [pkiTP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pkiTP/overview)) which can be configured using the [aci_](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/) resource. This attribute is supported in ACI versions: 4.0(1h) and later. + + #### Optional #### + + * `annotation` (annotation) - (string) The annotation of the Tp object. + - Default: `orchestrator:terraform` + * `target_dn` (tDn) - (string) The distinguished name of the target. + + * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + + * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + + * `key_ring` - (list) A list of Key Ring (ACI object [commRsKeyRing](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commRsKeyRing/overview)) pointing to (ACI Object [pkiKeyRing](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pkiKeyRing/overview)) which can be configured using the [aci_](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/) resource. + + #### Optional #### + + * `annotation` (annotation) - (string) The annotation of the Key Ring object. + - Default: `orchestrator:terraform` + * `tn_pki_key_ring_name` (tnPkiKeyRingName) - (string) The HTTP connection key ring. Each PKI device holds a pair of asymmetric Rivest-Shamir-Adleman (RSA) or Elliptic Curve Cryptography (ECC) encryption keys, one kept private and one made public, stored in an internal key ring. + + * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + + * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + + * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + + * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -211,4 +266,5 @@ import { ## Child Resources - - [aci_http_ssl_configuration](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/http_ssl_configuration) \ No newline at end of file + - [aci_http_ssl_configuration](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/http_ssl_configuration) + diff --git a/docs/resources/endpoint_tag_ip.md b/docs/resources/endpoint_tag_ip.md index 369bbb796..acf7b1069 100644 --- a/docs/resources/endpoint_tag_ip.md +++ b/docs/resources/endpoint_tag_ip.md @@ -95,14 +95,14 @@ All examples for the Endpoint Tag Ip resource can be found in the [examples](htt * `name_alias` (nameAlias) - (string) The name alias of the Endpoint Tag Ip object. * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -125,3 +125,5 @@ import { to = aci_endpoint_tag_ip.example_tenant } ``` + + diff --git a/docs/resources/endpoint_tag_mac.md b/docs/resources/endpoint_tag_mac.md index ee16a8ce0..0103f6d61 100644 --- a/docs/resources/endpoint_tag_mac.md +++ b/docs/resources/endpoint_tag_mac.md @@ -95,14 +95,14 @@ All examples for the Endpoint Tag Mac resource can be found in the [examples](ht * `name_alias` (nameAlias) - (string) The name alias of the Endpoint Tag Mac object. * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -125,3 +125,5 @@ import { to = aci_endpoint_tag_mac.example_tenant } ``` + + diff --git a/docs/resources/external_management_network_instance_profile.md b/docs/resources/external_management_network_instance_profile.md index 17c562f06..97d1ab8aa 100644 --- a/docs/resources/external_management_network_instance_profile.md +++ b/docs/resources/external_management_network_instance_profile.md @@ -97,11 +97,10 @@ All examples for the External Management Network Instance Profile resource can b - Valid Values: `level1`, `level2`, `level3`, `level4`, `level5`, `level6`, `unspecified`. * `relation_to_consumed_out_of_band_contracts` - (list) A list of Relation To Consumed Out Of Band Contracts (ACI object [mgmtRsOoBCons](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtRsOoBCons/overview)) pointing to Out Of Band Contract (ACI Object [vzOOBBrCP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/vzOOBBrCP/overview)) which can be configured using the [aci_out_of_band_contract](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/out_of_band_contract) resource. - + #### Required #### * `out_of_band_contract_name` (tnVzOOBBrCPName) - (string) The name of the Out Of Band Contract object. This attribute can be referenced from a [resource](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/out_of_band_contract) with `aci_out_of_band_contract.example.name` or from a [datasource](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/data-sources/out_of_band_contract) with `data.aci_out_of_band_contract.example.name`. - #### Optional #### * `annotation` (annotation) - (string) The annotation of the Relation To Consumed Out Of Band Contract object. @@ -110,15 +109,29 @@ All examples for the External Management Network Instance Profile resource can b - Default: `unspecified` - Valid Values: `level1`, `level2`, `level3`, `level4`, `level5`, `level6`, `unspecified`. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + + * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -144,4 +157,5 @@ import { ## Child Resources - - [aci_external_management_network_subnet](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_subnet) \ No newline at end of file + - [aci_external_management_network_subnet](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_subnet) + diff --git a/docs/resources/external_management_network_subnet.md b/docs/resources/external_management_network_subnet.md index 92432a2dd..214c57d1c 100644 --- a/docs/resources/external_management_network_subnet.md +++ b/docs/resources/external_management_network_subnet.md @@ -92,14 +92,14 @@ All examples for the External Management Network Subnet resource can be found in * `name_alias` (nameAlias) - (string) The name alias of the External Management Network Subnet object. * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -122,3 +122,5 @@ import { to = aci_external_management_network_subnet.example_external_management_network_instance_profile } ``` + + diff --git a/docs/resources/l3out_consumer_label.md b/docs/resources/l3out_consumer_label.md index 1cb74b2f5..383a70423 100644 --- a/docs/resources/l3out_consumer_label.md +++ b/docs/resources/l3out_consumer_label.md @@ -103,14 +103,14 @@ All examples for the L3out Consumer Label resource can be found in the [examples - Valid Values: `alice-blue`, `antique-white`, `aqua`, `aquamarine`, `azure`, `beige`, `bisque`, `black`, `blanched-almond`, `blue`, `blue-violet`, `brown`, `burlywood`, `cadet-blue`, `chartreuse`, `chocolate`, `coral`, `cornflower-blue`, `cornsilk`, `crimson`, `cyan`, `dark-blue`, `dark-cyan`, `dark-goldenrod`, `dark-gray`, `dark-green`, `dark-khaki`, `dark-magenta`, `dark-olive-green`, `dark-orange`, `dark-orchid`, `dark-red`, `dark-salmon`, `dark-sea-green`, `dark-slate-blue`, `dark-slate-gray`, `dark-turquoise`, `dark-violet`, `deep-pink`, `deep-sky-blue`, `dim-gray`, `dodger-blue`, `fire-brick`, `floral-white`, `forest-green`, `fuchsia`, `gainsboro`, `ghost-white`, `gold`, `goldenrod`, `gray`, `green`, `green-yellow`, `honeydew`, `hot-pink`, `indian-red`, `indigo`, `ivory`, `khaki`, `lavender`, `lavender-blush`, `lawn-green`, `lemon-chiffon`, `light-blue`, `light-coral`, `light-cyan`, `light-goldenrod-yellow`, `light-gray`, `light-green`, `light-pink`, `light-salmon`, `light-sea-green`, `light-sky-blue`, `light-slate-gray`, `light-steel-blue`, `light-yellow`, `lime`, `lime-green`, `linen`, `magenta`, `maroon`, `medium-aquamarine`, `medium-blue`, `medium-orchid`, `medium-purple`, `medium-sea-green`, `medium-slate-blue`, `medium-spring-green`, `medium-turquoise`, `medium-violet-red`, `midnight-blue`, `mint-cream`, `misty-rose`, `moccasin`, `navajo-white`, `navy`, `old-lace`, `olive`, `olive-drab`, `orange`, `orange-red`, `orchid`, `pale-goldenrod`, `pale-green`, `pale-turquoise`, `pale-violet-red`, `papaya-whip`, `peachpuff`, `peru`, `pink`, `plum`, `powder-blue`, `purple`, `red`, `rosy-brown`, `royal-blue`, `saddle-brown`, `salmon`, `sandy-brown`, `sea-green`, `seashell`, `sienna`, `silver`, `sky-blue`, `slate-blue`, `slate-gray`, `snow`, `spring-green`, `steel-blue`, `tan`, `teal`, `thistle`, `tomato`, `turquoise`, `violet`, `wheat`, `white`, `white-smoke`, `yellow`, `yellow-green`. * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -133,3 +133,5 @@ import { to = aci_l3out_consumer_label.example_l3_outside } ``` + + diff --git a/docs/resources/l3out_redistribute_policy.md b/docs/resources/l3out_redistribute_policy.md index 270843a8b..665ddc4e7 100644 --- a/docs/resources/l3out_redistribute_policy.md +++ b/docs/resources/l3out_redistribute_policy.md @@ -90,14 +90,14 @@ All examples for the L3out Redistribute Policy resource can be found in the [exa - Default: `orchestrator:terraform` * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -120,3 +120,5 @@ import { to = aci_l3out_redistribute_policy.example_l3_outside } ``` + + diff --git a/docs/resources/out_of_band_contract.md b/docs/resources/out_of_band_contract.md index 2f04bbf76..627d93bc9 100644 --- a/docs/resources/out_of_band_contract.md +++ b/docs/resources/out_of_band_contract.md @@ -106,14 +106,14 @@ All examples for the Out Of Band Contract resource can be found in the [examples - Valid Values: `AF11`, `AF12`, `AF13`, `AF21`, `AF22`, `AF23`, `AF31`, `AF32`, `AF33`, `AF41`, `AF42`, `AF43`, `CS0`, `CS1`, `CS2`, `CS3`, `CS4`, `CS5`, `CS6`, `CS7`, `EF`, `VA`, `unspecified`. * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -136,3 +136,5 @@ import { to = aci_out_of_band_contract.example } ``` + + diff --git a/docs/resources/pim_route_map_entry.md b/docs/resources/pim_route_map_entry.md index 0656563e3..fc23f5d3d 100644 --- a/docs/resources/pim_route_map_entry.md +++ b/docs/resources/pim_route_map_entry.md @@ -102,14 +102,14 @@ All examples for the Pim Route Map Entry resource can be found in the [examples] * `source_ip` (src) - (string) The source ip of the Pim Route Map Entry object. * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -132,3 +132,5 @@ import { to = aci_pim_route_map_entry.example_pim_route_map_policy } ``` + + diff --git a/docs/resources/pim_route_map_policy.md b/docs/resources/pim_route_map_policy.md index ab3d1c569..2ea77b74c 100644 --- a/docs/resources/pim_route_map_policy.md +++ b/docs/resources/pim_route_map_policy.md @@ -94,14 +94,14 @@ All examples for the Pim Route Map Policy resource can be found in the [examples * `owner_tag` (ownerTag) - (string) A tag for enabling clients to add their own data. For example, to indicate who created this object. * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -127,4 +127,5 @@ import { ## Child Resources - - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) \ No newline at end of file + - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) + diff --git a/docs/resources/relation_to_consumed_out_of_band_contract.md b/docs/resources/relation_to_consumed_out_of_band_contract.md index f9244a156..df95f927a 100644 --- a/docs/resources/relation_to_consumed_out_of_band_contract.md +++ b/docs/resources/relation_to_consumed_out_of_band_contract.md @@ -90,14 +90,14 @@ All examples for the Relation To Consumed Out Of Band Contract resource can be f - Valid Values: `level1`, `level2`, `level3`, `level4`, `level5`, `level6`, `unspecified`. * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -120,3 +120,5 @@ import { to = aci_relation_to_consumed_out_of_band_contract.example_external_management_network_instance_profile } ``` + + diff --git a/docs/resources/relation_to_fallback_route_group.md b/docs/resources/relation_to_fallback_route_group.md index c7acf8bd1..e42087d3a 100644 --- a/docs/resources/relation_to_fallback_route_group.md +++ b/docs/resources/relation_to_fallback_route_group.md @@ -86,14 +86,14 @@ All examples for the Relation To Fallback Route Group resource can be found in t - Default: `orchestrator:terraform` * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -116,3 +116,5 @@ import { to = aci_relation_to_fallback_route_group.example_l3_outside } ``` + + diff --git a/docs/resources/tag.md b/docs/resources/tag.md index 413d598ca..6cf8b4761 100644 --- a/docs/resources/tag.md +++ b/docs/resources/tag.md @@ -113,3 +113,5 @@ import { to = aci_tag.example_tenant } ``` + + diff --git a/docs/resources/vrf_fallback_route_group.md b/docs/resources/vrf_fallback_route_group.md index dbfacd95f..ff5874641 100644 --- a/docs/resources/vrf_fallback_route_group.md +++ b/docs/resources/vrf_fallback_route_group.md @@ -99,11 +99,10 @@ All examples for the VRF Fallback Route Group resource can be found in the [exam * `name_alias` (nameAlias) - (string) The name alias of the VRF Fallback Route Group object. * `vrf_fallback_route_group_members` - (list) A list of VRF Fallback Route Group Members (ACI object [fvFBRMember](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/fvFBRMember/overview)). VRF Fallback Route Group Members can also be configured using a separate [aci_vrf_fallback_route_group_member](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/vrf_fallback_route_group_member) resource. - + #### Required #### * `fallback_member` (rnhAddr) - (string) The address of the VRF Fallback Route Group Member object. - #### Optional #### * `annotation` (annotation) - (string) The annotation of the VRF Fallback Route Group Member object. @@ -112,15 +111,29 @@ All examples for the VRF Fallback Route Group resource can be found in the [exam * `name` (name) - (string) The name of the VRF Fallback Route Group Member object. * `name_alias` (nameAlias) - (string) The name alias of the VRF Fallback Route Group Member object. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + + * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -143,3 +156,5 @@ import { to = aci_vrf_fallback_route_group.example_vrf } ``` + + diff --git a/docs/resources/vrf_fallback_route_group_member.md b/docs/resources/vrf_fallback_route_group_member.md index 5a056816e..704b9825e 100644 --- a/docs/resources/vrf_fallback_route_group_member.md +++ b/docs/resources/vrf_fallback_route_group_member.md @@ -93,14 +93,14 @@ All examples for the VRF Fallback Route Group Member resource can be found in th * `name_alias` (nameAlias) - (string) The name alias of the VRF Fallback Route Group Member object. * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -123,3 +123,5 @@ import { to = aci_vrf_fallback_route_group_member.example_vrf_fallback_route_group } ``` + + diff --git a/gen/generator.go b/gen/generator.go index 1c706bc3b..2ae0149cc 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -104,6 +104,7 @@ var templateFuncs = template.FuncMap{ "getDevnetDocForClass": GetDevnetDocForClass, "lowerFirstCharacter": LowerFirstCharacter, "isListEmpty": func(stringList []string) bool { return len(stringList) == 0 }, + "addToTemplateProperties": AddToTemplateProperties, } // Global variables used for unique resource name setting based on label from meta data @@ -235,6 +236,44 @@ func LowerFirstCharacter(str string) string { return strings.ToLower(string(str[0])) + str[1:] } +func DictForTemplates(values ...interface{}) (map[string]interface{}, error) { + if len(values)%2 != 0 { + return nil, fmt.Errorf("invalid number of arguments passed to the dict") + } + dict := make(map[string]interface{}) + for i := 0; i < len(values); i += 2 { + key, ok := values[i].(string) + if !ok { + return nil, fmt.Errorf("dict keys must be strings") + } + dict[key] = values[i+1] + } + return dict, nil +} + +// AddToTemplate creates a copy of the context with the new fields provided in the form of key value pairs +func AddToTemplateProperties(model Model, values ...interface{}) (*Model, error) { + // Create a copy of the model + newModel := model + updates, err := DictForTemplates(values...) + if err != nil { + return nil, err + } + + if newModel.TemplateProperties == nil { + newModel.TemplateProperties = make(map[string]interface{}) + } + + for k, v := range newModel.TemplateProperties { + newModel.TemplateProperties[k] = v + } + for k, v := range updates { + newModel.TemplateProperties[k] = v + } + + return &newModel, nil +} + // Renders the templates and writes a file to the output directory func renderTemplate(templateName, outputFileName, outputPath string, outputData interface{}) { templateData, err := os.ReadFile(fmt.Sprintf("%s/%s", templatePath, templateName)) @@ -672,6 +711,7 @@ type Model struct { Properties map[string]Property NamedProperties map[string]Property Children map[string]Model + DirectParent *Model Configuration map[string]interface{} TestVars map[string]interface{} Definitions Definitions @@ -691,6 +731,7 @@ type Model struct { HasNamedProperties bool HasChildNamedProperties bool Include bool + TemplateProperties map[string]interface{} } // A Property represents a ACI class property @@ -781,6 +822,7 @@ func (m *Model) setClassModel(metaPath string, isChildIteration bool, definition m.Children = make(map[string]Model) for _, child := range m.ChildClasses { childModel := Model{PkgName: child} + childModel.setDirectParent(m) childModel.setClassModel(metaPath, true, definitions, []string{m.PkgName}, pkgNames, mainParentChildren, parentHierarchyList) m.Children[child] = childModel if childModel.HasValidValues { @@ -968,6 +1010,10 @@ func (m *Model) SetGrandParentName(parentList []string, parent string) { } } +func (m *Model) setDirectParent(parentModel *Model) { + m.DirectParent = parentModel +} + func reverseList(items []string) []string { reversedList := make([]string, len(items)) for i, item := range items { diff --git a/gen/templates/resource.md.tmpl b/gen/templates/resource.md.tmpl index 22cbaf925..c203e3bc7 100644 --- a/gen/templates/resource.md.tmpl +++ b/gen/templates/resource.md.tmpl @@ -115,32 +115,71 @@ All examples for the {{.ResourceNameAsDescription}} resource can be found in the {{- end}} {{- end}} {{- end}} -{{ range .Children }}{{$childVersion := .Versions}} +{{- range .Children }} +{{ $newCtx := addToTemplateProperties . "Indent" "" }} + {{- template "childResourcesAndProperties" $newCtx }} +{{- end}} + +## Importing + +An existing {{.ResourceNameAsDescription}} can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: + +``` +terraform import aci_{{- .ResourceName}}.example{{- if .DocumentationExamples}}_{{- $key := index .DocumentationExamples 0 }}{{getResourceName $key $.Definitions}}{{- end}} {{ index .DnFormats 0 }} +``` + +Starting in Terraform version 1.5, an existing {{.ResourceNameAsDescription}} can be imported +using [import blocks](https://developer.hashicorp.com/terraform/language/import) via the following configuration: + +``` +import { + id = "{{ index .DnFormats 0 }}" + to = aci_{{ .ResourceName}}.example{{- if .DocumentationExamples}}_{{- $key := index .DocumentationExamples 0 }}{{getResourceName $key $.Definitions}}{{- end}} +} +``` +{{ if .DocumentationChildren}} +## Child Resources + {{range .DocumentationChildren}} + - {{ . }} + {{- end}} +{{- end}} + +{{/* A sub template for joining all the class names as a single string. */}} +{{- define "childResourcesAndProperties" -}} +{{- $indent := .TemplateProperties.Indent }} +{{- $childVersion := .Versions }} {{- if ne .RelationshipClass ""}} -* `{{- .ResourceName}}` - (list) A list of {{getResourceNameAsDescription .ResourceName $.Definitions}} (ACI object {{getDevnetDocForClass .PkgName}}) pointing to {{getResourceNameAsDescription .RelationshipResourceName $.Definitions}} (ACI Object {{getDevnetDocForClass .RelationshipClass}}) which can be configured using the [aci_{{.RelationshipResourceName}}](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/{{.RelationshipResourceName}}) resource.{{if and (ne $.Versions .Versions) (ne .Versions "")}} This attribute is supported in ACI versions: {{ .Versions}}{{- end}} +{{ $indent }}* `{{- .ResourceName}}` - (list) A list of {{getResourceNameAsDescription .ResourceName $.Definitions}} (ACI object {{getDevnetDocForClass .PkgName}}) pointing to {{getResourceNameAsDescription .RelationshipResourceName $.Definitions}} (ACI Object {{getDevnetDocForClass .RelationshipClass}}) which can be configured using the [aci_{{.RelationshipResourceName}}](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/{{.RelationshipResourceName}}) resource.{{if and (ne .DirectParent.Versions .Versions) (ne .Versions "")}} This attribute is supported in ACI versions: {{ .Versions}}{{- end}} {{- else}} -* `{{- .ResourceName}}` - (list) A list of {{getResourceNameAsDescription .ResourceName $.Definitions}} (ACI object {{getDevnetDocForClass .PkgName}}). {{getResourceNameAsDescription .ResourceName $.Definitions}} can also be configured using a separate [aci_{{.ResourceNameDocReference}}](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/{{.ResourceNameDocReference}}) resource.{{if and (ne $.Versions .Versions) (ne .Versions "")}} This attribute is supported in ACI versions: {{ .Versions}}{{- end}} +{{ $indent }}* `{{- .ResourceName}}` - (list) A list of {{getResourceNameAsDescription .ResourceName $.Definitions}} (ACI object {{getDevnetDocForClass .PkgName}}). {{getResourceNameAsDescription .ResourceName $.Definitions}} can also be configured using a separate [aci_{{.ResourceNameDocReference}}](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/{{.ResourceNameDocReference}}) resource.{{if and (ne .DirectParent.Versions .Versions) (ne .Versions "")}} This attribute is supported in ACI versions: {{ .Versions}}{{- end}} {{- end}} - - #### Required #### +{{- $containsRequired := false }} + {{- range .Properties}} + {{- if or .IsNaming .IsRequired}} + {{- $containsRequired = true -}} + {{- end}} + {{- end}} + {{- if $containsRequired }} + {{ print " " }} + {{ $indent }}#### Required #### + {{- end }} {{ range .Properties}} {{- if or .IsNaming .IsRequired}} {{- if eq .ValueType "bitmask"}} - * `{{- overwriteProperty .PkgName .SnakeCaseName $.Definitions}}` ({{- .PropertyName}}) - (list) {{.Comment}}{{if ne $childVersion .Versions}} This attribute is supported in ACI versions: {{ .Versions}}{{- end}} + {{ $indent }}* `{{- overwriteProperty .PkgName .SnakeCaseName $.Definitions}}` ({{- .PropertyName}}) - (list) {{.Comment}}{{if ne $childVersion .Versions}} This attribute is supported in ACI versions: {{ .Versions}}{{- end}} {{- else}} - * `{{- overwriteProperty .PkgName .SnakeCaseName $.Definitions}}` ({{- .PropertyName}}) - (string) {{.Comment}}{{if ne .NamedPropertyClass ""}}{{$RName := getResourceName .NamedPropertyClass $.Definitions}} This attribute can be referenced from a [resource](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/{{$RName}}) with `aci_{{$RName}}.example.name` or from a [datasource](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/data-sources/{{$RName}}) with `data.aci_{{$RName}}.example.name`.{{end}}{{if ne $childVersion .Versions}} This attribute is supported in ACI versions: {{ .Versions}}{{- end}} + {{ $indent }}* `{{- overwriteProperty .PkgName .SnakeCaseName $.Definitions}}` ({{- .PropertyName}}) - (string) {{.Comment}}{{if ne .NamedPropertyClass ""}}{{$RName := getResourceName .NamedPropertyClass $.Definitions}} This attribute can be referenced from a [resource](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/{{$RName}}) with `aci_{{$RName}}.example.name` or from a [datasource](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/data-sources/{{$RName}}) with `data.aci_{{$RName}}.example.name`.{{end}}{{if ne $childVersion .Versions}} This attribute is supported in ACI versions: {{ .Versions}}{{- end}} {{- end}} {{- end}} {{- end}} {{- if .HasOptionalProperties}} - - #### Optional #### + {{ $indent }}#### Optional #### {{ range .Properties}} {{- if and (not .IsNaming) (not .IsRequired)}} {{- if eq .ValueType "bitmask"}} - * `{{- overwriteProperty .PkgName .SnakeCaseName $.Definitions}}` ({{- .PropertyName}}) - (list) {{.Comment}}{{if ne $childVersion .Versions}} This attribute is supported in ACI versions: {{ .Versions}}{{- end}} + {{ $indent }}* `{{- overwriteProperty .PkgName .SnakeCaseName $.Definitions}}` ({{- .PropertyName}}) - (list) {{.Comment}}{{if ne $childVersion .Versions}} This attribute is supported in ACI versions: {{ .Versions}}{{- end}} {{- else}} - * `{{- overwriteProperty .PkgName .SnakeCaseName $.Definitions}}` ({{- .PropertyName}}) - (string) {{.Comment}}{{if ne $childVersion .Versions}} This attribute is supported in ACI versions: {{ .Versions}}{{- end}} + {{ $indent }}* `{{- overwriteProperty .PkgName .SnakeCaseName $.Definitions}}` ({{- .PropertyName}}) - (string) {{.Comment}}{{if ne $childVersion .Versions}} This attribute is supported in ACI versions: {{ .Versions}}{{- end}} {{- end}} {{- if .DefaultValue }} - Default: `{{ .DefaultValue }}` @@ -151,27 +190,8 @@ All examples for the {{.ResourceNameAsDescription}} resource can be found in the {{- end}} {{- end}} {{- end}} -{{ end}} -## Importing - -An existing {{.ResourceNameAsDescription}} can be [imported](https://www.terraform.io/docs/import/index.html) into this resource with its distinguished name (DN), via the following command: - -``` -terraform import aci_{{- .ResourceName}}.example{{- if .DocumentationExamples}}_{{- $key := index .DocumentationExamples 0 }}{{getResourceName $key $.Definitions}}{{- end}} {{ index .DnFormats 0 }} -``` - -Starting in Terraform version 1.5, an existing {{.ResourceNameAsDescription}} can be imported -using [import blocks](https://developer.hashicorp.com/terraform/language/import) via the following configuration: - -``` -import { - id = "{{ index .DnFormats 0 }}" - to = aci_{{ .ResourceName}}.example{{- if .DocumentationExamples}}_{{- $key := index .DocumentationExamples 0 }}{{getResourceName $key $.Definitions}}{{- end}} -} -``` -{{ if .DocumentationChildren}} -## Child Resources - {{range .DocumentationChildren}} - - {{ . }} - {{- end}} -{{- end}} \ No newline at end of file +{{- range .Children }} +{{ $newCtx := addToTemplateProperties . "Indent" (print $indent " ") }} + {{- template "childResourcesAndProperties" $newCtx }} +{{- end }} +{{- end }} \ No newline at end of file From c23da5faf8480eac3f3158e42afc486a02b0f25c Mon Sep 17 00:00:00 2001 From: Shreyas Date: Thu, 16 May 2024 10:17:37 -0400 Subject: [PATCH 12/20] [ignore] Modified generartor to exclude resources that don't have their own resource in the provider from being displyed as child resources in the docs --- docs/resources/communication_policy.md | 3 --- gen/generator.go | 33 ++++++++++++++++++++++++-- gen/templates/resource.md.tmpl | 2 +- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/docs/resources/communication_policy.md b/docs/resources/communication_policy.md index 4d12771bc..fe9f46f99 100644 --- a/docs/resources/communication_policy.md +++ b/docs/resources/communication_policy.md @@ -264,7 +264,4 @@ import { } ``` -## Child Resources - - - [aci_http_ssl_configuration](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/http_ssl_configuration) diff --git a/gen/generator.go b/gen/generator.go index 2ae0149cc..c3eedeee1 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -115,6 +115,7 @@ var rnPrefix = map[string]string{} var targetRelationalPropertyClasses = map[string]string{} var alwaysIncludeChildren = []string{"tag:Annotation", "tag:Tag"} var excludeChildResourceNamesFromDocs = []string{"", "annotation", "tag"} +var excludeResources []interface{} func GetResourceNameAsDescription(s string, definitions Definitions) string { resourceName := cases.Title(language.English).String(strings.ReplaceAll(s, "_", " ")) @@ -341,6 +342,10 @@ func getClassModels(definitions Definitions) map[string]Model { classModel := Model{PkgName: pkgName} classModel.setClassModel(metaPath, false, definitions, []string{}, pkgNames, nil, nil) classModels[pkgName] = classModel + + if len(classModel.IdentifiedBy) == 0 || classModel.Exclude { + excludeResources = append(excludeResources, pkgName) + } } return classModels } @@ -598,7 +603,7 @@ func main() { for _, model := range classModels { // Only render resources and datasources when the class has a unique identifier or is marked as include in the classes definitions YAML file - if len(model.IdentifiedBy) > 0 || model.Include { + if (len(model.IdentifiedBy) > 0 && !model.Exclude) || model.Include { // All classmodels have been read, thus now the model, child and relational resources names can be set // When done before additional files would need to be opened and read which would slow down the generation process @@ -731,6 +736,7 @@ type Model struct { HasNamedProperties bool HasChildNamedProperties bool Include bool + Exclude bool TemplateProperties map[string]interface{} } @@ -788,6 +794,7 @@ func (m *Model) setClassModel(metaPath string, isChildIteration bool, definition m.SetClassDnFormats(classDetails) m.SetClassIdentifiers(classDetails) m.SetClassInclude() + m.SetClassExclude() m.SetClassAllowDelete(classDetails) m.SetClassContainedByAndParent(classDetails, parents) m.SetClassContains(classDetails) @@ -988,6 +995,18 @@ func (m *Model) SetClassInclude() { } } +func (m *Model) SetClassExclude() { + if classDetails, ok := m.Definitions.Classes[m.PkgName]; ok { + for key, value := range classDetails.(map[interface{}]interface{}) { + if key.(string) == "exclude" { + m.Exclude = value.(bool) + } else { + m.Exclude = false + } + } + } +} + func (m *Model) SetClassAllowDelete(classDetails interface{}) { if classDetails.(map[string]interface{})["isCreatableDeletable"].(string) == "never" || !AllowClassDelete(m.PkgName, m.Definitions) { m.AllowDelete = false @@ -1525,6 +1544,15 @@ func GetTestConfigVariableName(className string, midString string, parentClassNa return "" } +func resourcesExcluded(excludeResources []interface{}, containedClassName string) bool { + for _, item := range excludeResources { + if s, ok := item.(string); ok && s == containedClassName { + return true + } + } + return false +} + // Determine if possible dn formats in terraform documentation should be overwritten by dn formats from the classes.yaml file func GetOverwriteExampleClasses(classPkgName string, definitions Definitions) []interface{} { overwriteExampleClasses := []interface{}{} @@ -1633,7 +1661,8 @@ func setDocumentationData(m *Model, definitions Definitions) { // Add child class references to documentation when resource name is known for _, child := range m.Contains { match, _ := regexp.MatchString("[Rs][A-Z][^\r\n\t\f\v]", child) // match all Rs classes - if !match { + // fmt.Println(child, checkExistenceOfChild(m, child)) + if !match && !resourcesExcluded(excludeResources, child) { resourceName := GetResourceName(child, definitions) if !slices.Contains(excludeChildResourceNamesFromDocs, resourceName) { // exclude anotation children since they will be included into the resource when possible m.DocumentationChildren = append(m.DocumentationChildren, fmt.Sprintf("[%s_%s](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/%s)", providerName, resourceName, resourceName)) diff --git a/gen/templates/resource.md.tmpl b/gen/templates/resource.md.tmpl index c203e3bc7..2c4df1504 100644 --- a/gen/templates/resource.md.tmpl +++ b/gen/templates/resource.md.tmpl @@ -144,7 +144,7 @@ import { {{- end}} {{- end}} -{{/* A sub template for joining all the class names as a single string. */}} +{{/* A sub template for including nested children in the docs. */}} {{- define "childResourcesAndProperties" -}} {{- $indent := .TemplateProperties.Indent }} {{- $childVersion := .Versions }} From c69352ee32e0fd1dc02d168c700c63b0a3be001a Mon Sep 17 00:00:00 2001 From: Shreyas Date: Thu, 16 May 2024 14:21:02 -0400 Subject: [PATCH 13/20] [ignore] Go-generate rendered files to match with the latest --- docs/data-sources/annotation.md | 1 - docs/data-sources/tag.md | 1 - docs/resources/annotation.md | 1 - docs/resources/l3out_provider_label.md | 6 +- docs/resources/tag.md | 1 - .../resource_aci_l3out_provider_label.go | 120 +++++++++++++----- 6 files changed, 92 insertions(+), 38 deletions(-) diff --git a/docs/data-sources/annotation.md b/docs/data-sources/annotation.md index de979e7a3..05fd49635 100644 --- a/docs/data-sources/annotation.md +++ b/docs/data-sources/annotation.md @@ -77,7 +77,6 @@ data "aci_annotation" "example_application_epg" { - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) ======= - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) ([pimRouteMapEntry](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapEntry/overview)) - - [aci_pim_route_map_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_policy) ([pimRouteMapPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapPol/overview)) - Too many classes to display, see model documentation for all possible classes of [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview). >>>>>>> 1210cc50 ([ignore] Changed full identifier to parent hierarchy) * `key` (key) - (string) The key used to uniquely identify this configuration object. diff --git a/docs/data-sources/tag.md b/docs/data-sources/tag.md index 29b076fd7..55604f918 100644 --- a/docs/data-sources/tag.md +++ b/docs/data-sources/tag.md @@ -77,7 +77,6 @@ data "aci_tag" "example_application_epg" { - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) ======= - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) ([pimRouteMapEntry](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapEntry/overview)) - - [aci_pim_route_map_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_policy) ([pimRouteMapPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapPol/overview)) - Too many classes to display, see model documentation for all possible classes of [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview). >>>>>>> 1210cc50 ([ignore] Changed full identifier to parent hierarchy) * `key` (key) - (string) The key used to uniquely identify this configuration object. diff --git a/docs/resources/annotation.md b/docs/resources/annotation.md index 1e55bcf29..019a6b2cb 100644 --- a/docs/resources/annotation.md +++ b/docs/resources/annotation.md @@ -86,7 +86,6 @@ All examples for the Annotation resource can be found in the [examples](https:// - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) ======= - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) ([pimRouteMapEntry](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapEntry/overview)) - - [aci_pim_route_map_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_policy) ([pimRouteMapPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapPol/overview)) - Too many classes to display, see model documentation for all possible classes of [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview). >>>>>>> 1210cc50 ([ignore] Changed full identifier to parent hierarchy) * `key` (key) - (string) The key used to uniquely identify this configuration object. diff --git a/docs/resources/l3out_provider_label.md b/docs/resources/l3out_provider_label.md index ab76b2056..865924d62 100644 --- a/docs/resources/l3out_provider_label.md +++ b/docs/resources/l3out_provider_label.md @@ -97,14 +97,14 @@ All examples for the L3out Provider Label resource can be found in the [examples - Valid Values: `alice-blue`, `antique-white`, `aqua`, `aquamarine`, `azure`, `beige`, `bisque`, `black`, `blanched-almond`, `blue`, `blue-violet`, `brown`, `burlywood`, `cadet-blue`, `chartreuse`, `chocolate`, `coral`, `cornflower-blue`, `cornsilk`, `crimson`, `cyan`, `dark-blue`, `dark-cyan`, `dark-goldenrod`, `dark-gray`, `dark-green`, `dark-khaki`, `dark-magenta`, `dark-olive-green`, `dark-orange`, `dark-orchid`, `dark-red`, `dark-salmon`, `dark-sea-green`, `dark-slate-blue`, `dark-slate-gray`, `dark-turquoise`, `dark-violet`, `deep-pink`, `deep-sky-blue`, `dim-gray`, `dodger-blue`, `fire-brick`, `floral-white`, `forest-green`, `fuchsia`, `gainsboro`, `ghost-white`, `gold`, `goldenrod`, `gray`, `green`, `green-yellow`, `honeydew`, `hot-pink`, `indian-red`, `indigo`, `ivory`, `khaki`, `lavender`, `lavender-blush`, `lawn-green`, `lemon-chiffon`, `light-blue`, `light-coral`, `light-cyan`, `light-goldenrod-yellow`, `light-gray`, `light-green`, `light-pink`, `light-salmon`, `light-sea-green`, `light-sky-blue`, `light-slate-gray`, `light-steel-blue`, `light-yellow`, `lime`, `lime-green`, `linen`, `magenta`, `maroon`, `medium-aquamarine`, `medium-blue`, `medium-orchid`, `medium-purple`, `medium-sea-green`, `medium-slate-blue`, `medium-spring-green`, `medium-turquoise`, `medium-violet-red`, `midnight-blue`, `mint-cream`, `misty-rose`, `moccasin`, `navajo-white`, `navy`, `old-lace`, `olive`, `olive-drab`, `orange`, `orange-red`, `orchid`, `pale-goldenrod`, `pale-green`, `pale-turquoise`, `pale-violet-red`, `papaya-whip`, `peachpuff`, `peru`, `pink`, `plum`, `powder-blue`, `purple`, `red`, `rosy-brown`, `royal-blue`, `saddle-brown`, `salmon`, `sandy-brown`, `sea-green`, `seashell`, `sienna`, `silver`, `sky-blue`, `slate-blue`, `slate-gray`, `snow`, `spring-green`, `steel-blue`, `tan`, `teal`, `thistle`, `tomato`, `turquoise`, `violet`, `wheat`, `white`, `white-smoke`, `yellow`, `yellow-green`. * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -127,3 +127,5 @@ import { to = aci_l3out_provider_label.example_l3_outside } ``` + + diff --git a/docs/resources/tag.md b/docs/resources/tag.md index 6cf8b4761..e4a438f78 100644 --- a/docs/resources/tag.md +++ b/docs/resources/tag.md @@ -86,7 +86,6 @@ All examples for the Tag resource can be found in the [examples](https://github. - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) ======= - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) ([pimRouteMapEntry](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapEntry/overview)) - - [aci_pim_route_map_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_policy) ([pimRouteMapPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapPol/overview)) - Too many classes to display, see model documentation for all possible classes of [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview). >>>>>>> 1210cc50 ([ignore] Changed full identifier to parent hierarchy) * `key` (key) - (string) The key used to uniquely identify this configuration object. diff --git a/internal/provider/resource_aci_l3out_provider_label.go b/internal/provider/resource_aci_l3out_provider_label.go index fba072364..39750e112 100644 --- a/internal/provider/resource_aci_l3out_provider_label.go +++ b/internal/provider/resource_aci_l3out_provider_label.go @@ -14,6 +14,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -62,12 +63,34 @@ type TagAnnotationL3extProvLblResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationL3extProvLblResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationL3extProvLblResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationL3extProvLblResourceModelAttributeTypes()) +} + // TagTagL3extProvLblResourceModel describes the resource data model for the children without relation ships. type TagTagL3extProvLblResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagL3extProvLblResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagL3extProvLblResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagL3extProvLblResourceModelAttributeTypes()) +} + type L3extProvLblIdentifier struct { Name types.String } @@ -105,6 +128,7 @@ func (r *L3extProvLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the L3out Provider Label object.`, @@ -114,6 +138,7 @@ func (r *L3extProvLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The description of the L3out Provider Label object.`, }, @@ -121,6 +146,7 @@ func (r *L3extProvLblResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The name of the L3out Provider Label object.`, @@ -130,6 +156,7 @@ func (r *L3extProvLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the L3out Provider Label object.`, }, @@ -138,6 +165,7 @@ func (r *L3extProvLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key for enabling clients to own their data for entity correlation.`, }, @@ -146,6 +174,7 @@ func (r *L3extProvLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `A tag for enabling clients to add their own data. For example, to indicate who created this object.`, }, @@ -154,6 +183,7 @@ func (r *L3extProvLblResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Validators: []validator.String{ stringvalidator.OneOf("alice-blue", "antique-white", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanched-almond", "blue", "blue-violet", "brown", "burlywood", "cadet-blue", "chartreuse", "chocolate", "coral", "cornflower-blue", "cornsilk", "crimson", "cyan", "dark-blue", "dark-cyan", "dark-goldenrod", "dark-gray", "dark-green", "dark-khaki", "dark-magenta", "dark-olive-green", "dark-orange", "dark-orchid", "dark-red", "dark-salmon", "dark-sea-green", "dark-slate-blue", "dark-slate-gray", "dark-turquoise", "dark-violet", "deep-pink", "deep-sky-blue", "dim-gray", "dodger-blue", "fire-brick", "floral-white", "forest-green", "fuchsia", "gainsboro", "ghost-white", "gold", "goldenrod", "gray", "green", "green-yellow", "honeydew", "hot-pink", "indian-red", "indigo", "ivory", "khaki", "lavender", "lavender-blush", "lawn-green", "lemon-chiffon", "light-blue", "light-coral", "light-cyan", "light-goldenrod-yellow", "light-gray", "light-green", "light-pink", "light-salmon", "light-sea-green", "light-sky-blue", "light-slate-gray", "light-steel-blue", "light-yellow", "lime", "lime-green", "linen", "magenta", "maroon", "medium-aquamarine", "medium-blue", "medium-orchid", "medium-purple", "medium-sea-green", "medium-slate-blue", "medium-spring-green", "medium-turquoise", "medium-violet-red", "midnight-blue", "mint-cream", "misty-rose", "moccasin", "navajo-white", "navy", "old-lace", "olive", "olive-drab", "orange", "orange-red", "orchid", "pale-goldenrod", "pale-green", "pale-turquoise", "pale-violet-red", "papaya-whip", "peachpuff", "peru", "pink", "plum", "powder-blue", "purple", "red", "rosy-brown", "royal-blue", "saddle-brown", "salmon", "sandy-brown", "sea-green", "seashell", "sienna", "silver", "sky-blue", "slate-blue", "slate-gray", "snow", "spring-green", "steel-blue", "tan", "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", "white-smoke", "yellow", "yellow-green"), @@ -173,6 +203,7 @@ func (r *L3extProvLblResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -180,6 +211,7 @@ func (r *L3extProvLblResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -199,6 +231,7 @@ func (r *L3extProvLblResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -206,6 +239,7 @@ func (r *L3extProvLblResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -385,7 +419,7 @@ func (r *L3extProvLblResource) ImportState(ctx context.Context, req resource.Imp } func getAndSetL3extProvLblAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *L3extProvLblResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "l3extProvLbl,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "l3extProvLbl,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -421,7 +455,30 @@ func getAndSetL3extProvLblAttributes(ctx context.Context, diags *diag.Diagnostic data.Tag = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.Descr.IsUnknown() { + data.Descr = types.StringNull() + } + if data.Name.IsUnknown() { + data.Name = types.StringNull() + } + if data.NameAlias.IsUnknown() { + data.NameAlias = types.StringNull() + } + if data.OwnerKey.IsUnknown() { + data.OwnerKey = types.StringNull() + } + if data.OwnerTag.IsUnknown() { + data.OwnerTag = types.StringNull() + } + if data.Tag.IsUnknown() { + data.Tag = types.StringNull() + } + TagAnnotationL3extProvLbl := TagAnnotationL3extProvLblResourceModel{} TagAnnotationL3extProvLblList := make([]TagAnnotationL3extProvLblResourceModel, 0) + TagTagL3extProvLbl := TagTagL3extProvLblResourceModel{} TagTagL3extProvLblList := make([]TagTagL3extProvLblResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -430,7 +487,6 @@ func getAndSetL3extProvLblAttributes(ctx context.Context, diags *diag.Diagnostic for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "tagAnnotation" { - TagAnnotationL3extProvLbl := TagAnnotationL3extProvLblResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationL3extProvLbl.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -438,11 +494,11 @@ func getAndSetL3extProvLblAttributes(ctx context.Context, diags *diag.Diagnostic if childAttributeName == "value" { TagAnnotationL3extProvLbl.Value = basetypes.NewStringValue(childAttributeValue.(string)) } + } TagAnnotationL3extProvLblList = append(TagAnnotationL3extProvLblList, TagAnnotationL3extProvLbl) } if childClassName == "tagTag" { - TagTagL3extProvLbl := TagTagL3extProvLblResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagL3extProvLbl.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -450,6 +506,7 @@ func getAndSetL3extProvLblAttributes(ctx context.Context, diags *diag.Diagnostic if childAttributeName == "value" { TagTagL3extProvLbl.Value = basetypes.NewStringValue(childAttributeValue.(string)) } + } TagTagL3extProvLblList = append(TagTagL3extProvLblList, TagTagL3extProvLbl) } @@ -502,25 +559,24 @@ func setL3extProvLblId(ctx context.Context, data *L3extProvLblResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getL3extProvLblTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extProvLblResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationL3extProvLblResourceModel) []map[string]interface{} { - +func getL3extProvLblTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extProvLblResourceModel, tagAnnotationL3extProvLblPlan, tagAnnotationL3extProvLblState []TagAnnotationL3extProvLblResourceModel) []map[string]interface{} { childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationL3extProvLbl := range tagAnnotationL3extProvLblPlan { + childMap := NewAciObject() + if !tagAnnotationL3extProvLbl.Key.IsNull() && !tagAnnotationL3extProvLbl.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationL3extProvLbl.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationL3extProvLbl.Value.IsNull() && !tagAnnotationL3extProvLbl.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationL3extProvLbl.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationL3extProvLbl.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationL3extProvLblState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -529,10 +585,10 @@ func getL3extProvLblTagAnnotationChildPayloads(ctx context.Context, diags *diag. } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -541,25 +597,25 @@ func getL3extProvLblTagAnnotationChildPayloads(ctx context.Context, diags *diag. return childPayloads } -func getL3extProvLblTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extProvLblResourceModel, tagTagPlan, tagTagState []TagTagL3extProvLblResourceModel) []map[string]interface{} { +func getL3extProvLblTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *L3extProvLblResourceModel, tagTagL3extProvLblPlan, tagTagL3extProvLblState []TagTagL3extProvLblResourceModel) []map[string]interface{} { childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + for _, tagTagL3extProvLbl := range tagTagL3extProvLblPlan { + childMap := NewAciObject() + if !tagTagL3extProvLbl.Key.IsNull() && !tagTagL3extProvLbl.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagL3extProvLbl.Key.ValueString() } - if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + if !tagTagL3extProvLbl.Value.IsNull() && !tagTagL3extProvLbl.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagL3extProvLbl.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagL3extProvLbl.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagL3extProvLblState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { @@ -568,10 +624,10 @@ func getL3extProvLblTagTagChildPayloads(ctx context.Context, diags *diag.Diagnos } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { From c340d0f3ab49255ad04ea0f9439f5a8d1c960296 Mon Sep 17 00:00:00 2001 From: Shreyas Date: Fri, 17 May 2024 08:13:14 -0400 Subject: [PATCH 14/20] [ignore] Made changes to the generator to exclude objects that don't have their own stand-alone resources within DocumentationParentDNs used for the docs --- docs/data-sources/annotation.md | 4 ++++ docs/data-sources/tag.md | 4 ++++ docs/resources/annotation.md | 6 +----- docs/resources/tag.md | 6 +----- gen/generator.go | 12 +++++++----- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/docs/data-sources/annotation.md b/docs/data-sources/annotation.md index 05fd49635..58633ce92 100644 --- a/docs/data-sources/annotation.md +++ b/docs/data-sources/annotation.md @@ -54,6 +54,7 @@ data "aci_annotation" "example_application_epg" { * `parent_dn` - (string) The distinguished name (DN) of the parent object, possible resources: - Too many parent DNs to display, see model documentation for all possible parents of [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview). + - [aci_communication_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/communication_policy) ([commPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commPol/overview)) - [aci_application_epg](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/application_epg) ([fvAEPg](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/fvAEPg/overview)) - [aci_vrf](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/vrf) ([fvCtx](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/fvCtx/overview)) - [aci_endpoint_tag_ip](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/endpoint_tag_ip) ([fvEpIpTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/fvEpIpTag/overview)) @@ -77,6 +78,9 @@ data "aci_annotation" "example_application_epg" { - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) ======= - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) ([pimRouteMapEntry](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapEntry/overview)) + - [aci_pim_route_map_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_policy) ([pimRouteMapPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapPol/overview)) + - [aci_route_control_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/route_control_profile) ([rtctrlProfile](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/rtctrlProfile/overview)) + - [aci_contract_interface](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/contract_interface) ([vzCPIf](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/vzCPIf/overview)) - Too many classes to display, see model documentation for all possible classes of [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview). >>>>>>> 1210cc50 ([ignore] Changed full identifier to parent hierarchy) * `key` (key) - (string) The key used to uniquely identify this configuration object. diff --git a/docs/data-sources/tag.md b/docs/data-sources/tag.md index 55604f918..39b977dcc 100644 --- a/docs/data-sources/tag.md +++ b/docs/data-sources/tag.md @@ -54,6 +54,7 @@ data "aci_tag" "example_application_epg" { * `parent_dn` - (string) The distinguished name (DN) of the parent object, possible resources: - Too many parent DNs to display, see model documentation for all possible parents of [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview). + - [aci_communication_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/communication_policy) ([commPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commPol/overview)) - [aci_application_epg](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/application_epg) ([fvAEPg](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/fvAEPg/overview)) - [aci_vrf](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/vrf) ([fvCtx](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/fvCtx/overview)) - [aci_endpoint_tag_ip](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/endpoint_tag_ip) ([fvEpIpTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/fvEpIpTag/overview)) @@ -77,6 +78,9 @@ data "aci_tag" "example_application_epg" { - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) ======= - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) ([pimRouteMapEntry](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapEntry/overview)) + - [aci_pim_route_map_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_policy) ([pimRouteMapPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapPol/overview)) + - [aci_route_control_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/route_control_profile) ([rtctrlProfile](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/rtctrlProfile/overview)) + - [aci_contract_interface](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/contract_interface) ([vzCPIf](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/vzCPIf/overview)) - Too many classes to display, see model documentation for all possible classes of [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview). >>>>>>> 1210cc50 ([ignore] Changed full identifier to parent hierarchy) * `key` (key) - (string) The key used to uniquely identify this configuration object. diff --git a/docs/resources/annotation.md b/docs/resources/annotation.md index 019a6b2cb..8411a91dd 100644 --- a/docs/resources/annotation.md +++ b/docs/resources/annotation.md @@ -63,6 +63,7 @@ All examples for the Annotation resource can be found in the [examples](https:// * `parent_dn` - (string) The distinguished name (DN) of the parent object, possible resources: - Too many parent DNs to display, see model documentation for all possible parents of [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview). + - [aci_communication_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/communication_policy) ([commPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commPol/overview)) - [aci_application_epg](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/application_epg) ([fvAEPg](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/fvAEPg/overview)) - [aci_vrf](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/vrf) ([fvCtx](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/fvCtx/overview)) - [aci_endpoint_tag_ip](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/endpoint_tag_ip) ([fvEpIpTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/fvEpIpTag/overview)) @@ -81,13 +82,8 @@ All examples for the Annotation resource can be found in the [examples](https:// - [aci_external_management_network_instance_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_instance_profile) ([mgmtInstP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtInstP/overview)) - [aci_relation_to_consumed_out_of_band_contract](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/relation_to_consumed_out_of_band_contract) ([mgmtRsOoBCons](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtRsOoBCons/overview)) - [aci_external_management_network_subnet](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_subnet) ([mgmtSubnet](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtSubnet/overview)) -<<<<<<< HEAD - [aci_l3out_node_sid_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/l3out_node_sid_profile) ([mplsNodeSidP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mplsNodeSidP/overview)) - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) -======= - - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) ([pimRouteMapEntry](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapEntry/overview)) - - Too many classes to display, see model documentation for all possible classes of [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview). ->>>>>>> 1210cc50 ([ignore] Changed full identifier to parent hierarchy) * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. diff --git a/docs/resources/tag.md b/docs/resources/tag.md index e4a438f78..366a91cf3 100644 --- a/docs/resources/tag.md +++ b/docs/resources/tag.md @@ -63,6 +63,7 @@ All examples for the Tag resource can be found in the [examples](https://github. * `parent_dn` - (string) The distinguished name (DN) of the parent object, possible resources: - Too many parent DNs to display, see model documentation for all possible parents of [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview). + - [aci_communication_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/communication_policy) ([commPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/commPol/overview)) - [aci_application_epg](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/application_epg) ([fvAEPg](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/fvAEPg/overview)) - [aci_vrf](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/vrf) ([fvCtx](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/fvCtx/overview)) - [aci_endpoint_tag_ip](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/endpoint_tag_ip) ([fvEpIpTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/fvEpIpTag/overview)) @@ -81,13 +82,8 @@ All examples for the Tag resource can be found in the [examples](https://github. - [aci_external_management_network_instance_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_instance_profile) ([mgmtInstP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtInstP/overview)) - [aci_relation_to_consumed_out_of_band_contract](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/relation_to_consumed_out_of_band_contract) ([mgmtRsOoBCons](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtRsOoBCons/overview)) - [aci_external_management_network_subnet](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_subnet) ([mgmtSubnet](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtSubnet/overview)) -<<<<<<< HEAD - [aci_l3out_node_sid_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/l3out_node_sid_profile) ([mplsNodeSidP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mplsNodeSidP/overview)) - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) -======= - - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) ([pimRouteMapEntry](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapEntry/overview)) - - Too many classes to display, see model documentation for all possible classes of [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview). ->>>>>>> 1210cc50 ([ignore] Changed full identifier to parent hierarchy) * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. diff --git a/gen/generator.go b/gen/generator.go index c3eedeee1..b0689ef08 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -1600,11 +1600,13 @@ func setDocumentationData(m *Model, definitions Definitions) { resourcesFound := [][]string{} resourcesNotFound := []string{} for _, containedClassName := range m.ContainedBy { - resourceName := GetResourceName(containedClassName, definitions) - if resourceName != "" { - resourcesFound = append(resourcesFound, []string{resourceName, containedClassName}) - } else { - resourcesNotFound = append(resourcesNotFound, containedClassName) + if !resourcesExcluded(excludeResources, containedClassName) { + resourceName := GetResourceName(containedClassName, definitions) + if resourceName != "" { + resourcesFound = append(resourcesFound, []string{resourceName, containedClassName}) + } else { + resourcesNotFound = append(resourcesNotFound, containedClassName) + } } } From 37e2f497e5985d71ef3537c716eff67045912cf1 Mon Sep 17 00:00:00 2001 From: Shreyas Date: Wed, 22 May 2024 12:09:31 -0400 Subject: [PATCH 15/20] [ignore] Modified resource examples template to incorporate grandchildren using recursive sub-templates --- .github/workflows/checks.yml | 3 +- docs/resources/communication_policy.md | 98 ++++++++++++++----- docs/resources/endpoint_tag_ip.md | 6 +- docs/resources/endpoint_tag_mac.md | 6 +- ...nal_management_network_instance_profile.md | 22 ++++- .../external_management_network_subnet.md | 6 +- docs/resources/l3out_consumer_label.md | 6 +- docs/resources/l3out_provider_label.md | 6 +- docs/resources/l3out_redistribute_policy.md | 6 +- docs/resources/out_of_band_contract.md | 6 +- docs/resources/pim_route_map_entry.md | 6 +- docs/resources/pim_route_map_policy.md | 6 +- ...lation_to_consumed_out_of_band_contract.md | 6 +- .../relation_to_fallback_route_group.md | 6 +- docs/resources/vrf_fallback_route_group.md | 26 +++-- .../vrf_fallback_route_group_member.md | 6 +- .../resource-all-attributes.tf | 98 ++++++++++++++----- .../resource-all-attributes.tf | 6 +- .../resource-all-attributes.tf | 6 +- .../resource-all-attributes.tf | 22 ++++- .../resource-all-attributes.tf | 6 +- .../resource-all-attributes.tf | 6 +- .../resource-all-attributes.tf | 6 +- .../resource-all-attributes.tf | 6 +- .../resource-all-attributes.tf | 6 +- .../resource-all-attributes.tf | 6 +- .../resource-all-attributes.tf | 6 +- .../resource-all-attributes.tf | 6 +- .../resource-all-attributes.tf | 6 +- .../resource-all-attributes.tf | 26 +++-- .../resource-all-attributes.tf | 6 +- .../resource_example_all_attributes.tf.tmpl | 27 ++--- 32 files changed, 337 insertions(+), 129 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 47c9dccac..81756fa97 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -76,12 +76,13 @@ jobs: terraform_version: '1.7.*' terraform_wrapper: false - name: Terraform Acceptance Test (APIC ${{ matrix.apic_host.name }}) - run: go test github.com/CiscoDevNet/terraform-provider-aci/v2/internal/provider -v -timeout 300m -coverprofile=coverage.out -covermode=atomic + run: go test github.com/CiscoDevNet/terraform-provider-aci/v2/internal/provider -v -timeout 300m -race -coverprofile=coverage.out -covermode=atomic env: TF_ACC: '1' TF_ACC_STATE_LINEAGE: '1' ACI_VAL_REL_DN: false ACI_URL: ${{ matrix.apic_host.url }} + GOMAXPROCS: '1' - name: Upload coverage to Codecov # Upload Coverage on latest only if: ${{ matrix.apic_host.name == 'v6.0'}} diff --git a/docs/resources/communication_policy.md b/docs/resources/communication_policy.md index fe9f46f99..4cf8e4d9c 100644 --- a/docs/resources/communication_policy.md +++ b/docs/resources/communication_policy.md @@ -55,44 +55,94 @@ resource "aci_communication_policy" "full_example" { strict_security_on_apic_oob_subnet = "no" http_ssl_configuration = [ { - access_control_allow_credential = "disabled" - access_control_allow_origins = "access_control_allow_origins_1" - admin_st = "disabled" - annotation = "annotation_1" - cli_only_mode = "disabled" - client_cert_auth_state = "disabled" - description = "description_1" - dh_param = "1024" - global_throttle_rate = "global_throttle_rate_1" - global_throttle_st = "disabled" - global_throttle_unit = "global_throttle_unit_1" - max_request_status_count = "max_request_status_count_1" - name = "name_1" - name_alias = "name_alias_1" - node_exporter = "disabled" - port = "port_1" - referer = "referer_1" - server_header = "disabled" - ssl_protocols = "TLSv1" - throttle_rate = "throttle_rate_1" - throttle_st = "disabled" - visore_access = "disabled" + access_control_allow_credential = "access_control_allow_credential_0" + access_control_allow_origins = "access_control_allow_origins_0" + admin_st = "admin_st_0" + annotation = "annotation_0" + cli_only_mode = "cli_only_mode_0" + client_cert_auth_state = "client_cert_auth_state_0" + description = "description_0" + dh_param = "dh_param_0" + global_throttle_rate = "global_throttle_rate_0" + global_throttle_st = "global_throttle_st_0" + global_throttle_unit = "global_throttle_unit_0" + max_request_status_count = "max_request_status_count_0" + name = "name_0" + name_alias = "name_alias_0" + node_exporter = "node_exporter_0" + port = "port_0" + referer = "referer_0" + server_header = "server_header_0" + ssl_protocols = "ssl_protocols_0" + throttle_rate = "throttle_rate_0" + throttle_st = "throttle_st_0" + visore_access = "visore_access_0" + tp = [ + { + annotation = "annotation_0" + target_dn = "target_dn_0" + annotations = [ + { + key = "key_0" + value = "value_0" + } + ] + tags = [ + { + key = "key_0" + value = "value_0" + } + ] + } + ] + key_ring = [ + { + annotation = "annotation_0" + tn_pki_key_ring_name = aci_.example.name + annotations = [ + { + key = "key_0" + value = "value_0" + } + ] + tags = [ + { + key = "key_0" + value = "value_0" + } + ] + } + ] + annotations = [ + { + key = "key_0" + value = "value_0" + } + ] + tags = [ + { + key = "key_0" + value = "value_0" + } + ] } ] annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the Communication Policy resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_communication_policy) folder. diff --git a/docs/resources/endpoint_tag_ip.md b/docs/resources/endpoint_tag_ip.md index acf7b1069..152e339d8 100644 --- a/docs/resources/endpoint_tag_ip.md +++ b/docs/resources/endpoint_tag_ip.md @@ -58,17 +58,19 @@ resource "aci_endpoint_tag_ip" "full_example_tenant" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the Endpoint Tag Ip resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_endpoint_tag_ip) folder. diff --git a/docs/resources/endpoint_tag_mac.md b/docs/resources/endpoint_tag_mac.md index 0103f6d61..b277f791e 100644 --- a/docs/resources/endpoint_tag_mac.md +++ b/docs/resources/endpoint_tag_mac.md @@ -58,17 +58,19 @@ resource "aci_endpoint_tag_mac" "full_example_tenant" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the Endpoint Tag Mac resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_endpoint_tag_mac) folder. diff --git a/docs/resources/external_management_network_instance_profile.md b/docs/resources/external_management_network_instance_profile.md index 97d1ab8aa..0a5ca8a2e 100644 --- a/docs/resources/external_management_network_instance_profile.md +++ b/docs/resources/external_management_network_instance_profile.md @@ -53,25 +53,39 @@ resource "aci_external_management_network_instance_profile" "full_example" { priority = "level1" relation_to_consumed_out_of_band_contracts = [ { - annotation = "annotation_1" - priority = "level1" + annotation = "annotation_0" + priority = "priority_0" out_of_band_contract_name = aci_out_of_band_contract.example.name + annotations = [ + { + key = "key_0" + value = "value_0" + } + ] + tags = [ + { + key = "key_0" + value = "value_0" + } + ] } ] annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the External Management Network Instance Profile resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_external_management_network_instance_profile) folder. diff --git a/docs/resources/external_management_network_subnet.md b/docs/resources/external_management_network_subnet.md index 214c57d1c..0a70f4d37 100644 --- a/docs/resources/external_management_network_subnet.md +++ b/docs/resources/external_management_network_subnet.md @@ -56,17 +56,19 @@ resource "aci_external_management_network_subnet" "full_example_external_managem annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the External Management Network Subnet resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_external_management_network_subnet) folder. diff --git a/docs/resources/l3out_consumer_label.md b/docs/resources/l3out_consumer_label.md index 383a70423..e4de2e417 100644 --- a/docs/resources/l3out_consumer_label.md +++ b/docs/resources/l3out_consumer_label.md @@ -61,17 +61,19 @@ resource "aci_l3out_consumer_label" "full_example_l3_outside" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the L3out Consumer Label resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_l3out_consumer_label) folder. diff --git a/docs/resources/l3out_provider_label.md b/docs/resources/l3out_provider_label.md index 865924d62..945d58418 100644 --- a/docs/resources/l3out_provider_label.md +++ b/docs/resources/l3out_provider_label.md @@ -58,17 +58,19 @@ resource "aci_l3out_provider_label" "full_example_l3_outside" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the L3out Provider Label resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_l3out_provider_label) folder. diff --git a/docs/resources/l3out_redistribute_policy.md b/docs/resources/l3out_redistribute_policy.md index 665ddc4e7..8d9ea3b8d 100644 --- a/docs/resources/l3out_redistribute_policy.md +++ b/docs/resources/l3out_redistribute_policy.md @@ -55,17 +55,19 @@ resource "aci_l3out_redistribute_policy" "full_example_l3_outside" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the L3out Redistribute Policy resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_l3out_redistribute_policy) folder. diff --git a/docs/resources/out_of_band_contract.md b/docs/resources/out_of_band_contract.md index 627d93bc9..70afb7665 100644 --- a/docs/resources/out_of_band_contract.md +++ b/docs/resources/out_of_band_contract.md @@ -59,17 +59,19 @@ resource "aci_out_of_band_contract" "full_example" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the Out Of Band Contract resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_out_of_band_contract) folder. diff --git a/docs/resources/pim_route_map_entry.md b/docs/resources/pim_route_map_entry.md index fc23f5d3d..0c1823ca2 100644 --- a/docs/resources/pim_route_map_entry.md +++ b/docs/resources/pim_route_map_entry.md @@ -60,17 +60,19 @@ resource "aci_pim_route_map_entry" "full_example_pim_route_map_policy" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the Pim Route Map Entry resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_pim_route_map_entry) folder. diff --git a/docs/resources/pim_route_map_policy.md b/docs/resources/pim_route_map_policy.md index 2ea77b74c..3d5aaf799 100644 --- a/docs/resources/pim_route_map_policy.md +++ b/docs/resources/pim_route_map_policy.md @@ -57,17 +57,19 @@ resource "aci_pim_route_map_policy" "full_example_tenant" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the Pim Route Map Policy resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_pim_route_map_policy) folder. diff --git a/docs/resources/relation_to_consumed_out_of_band_contract.md b/docs/resources/relation_to_consumed_out_of_band_contract.md index df95f927a..199529a42 100644 --- a/docs/resources/relation_to_consumed_out_of_band_contract.md +++ b/docs/resources/relation_to_consumed_out_of_band_contract.md @@ -54,17 +54,19 @@ resource "aci_relation_to_consumed_out_of_band_contract" "full_example_external_ annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the Relation To Consumed Out Of Band Contract resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_relation_to_consumed_out_of_band_contract) folder. diff --git a/docs/resources/relation_to_fallback_route_group.md b/docs/resources/relation_to_fallback_route_group.md index e42087d3a..3b37cdb78 100644 --- a/docs/resources/relation_to_fallback_route_group.md +++ b/docs/resources/relation_to_fallback_route_group.md @@ -53,17 +53,19 @@ resource "aci_relation_to_fallback_route_group" "full_example_l3_outside" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the Relation To Fallback Route Group resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_relation_to_fallback_route_group) folder. diff --git a/docs/resources/vrf_fallback_route_group.md b/docs/resources/vrf_fallback_route_group.md index ff5874641..a191f6e95 100644 --- a/docs/resources/vrf_fallback_route_group.md +++ b/docs/resources/vrf_fallback_route_group.md @@ -54,27 +54,41 @@ resource "aci_vrf_fallback_route_group" "full_example_vrf" { name_alias = "name_alias" vrf_fallback_route_group_members = [ { - annotation = "annotation_1" - description = "description_1" - name = "name_1" - name_alias = "name_alias_1" + annotation = "annotation_0" + description = "description_0" + name = "name_0" + name_alias = "name_alias_0" fallback_member = "2.2.2.2" + annotations = [ + { + key = "key_0" + value = "value_0" + } + ] + tags = [ + { + key = "key_0" + value = "value_0" + } + ] } ] annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the VRF Fallback Route Group resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_vrf_fallback_route_group) folder. diff --git a/docs/resources/vrf_fallback_route_group_member.md b/docs/resources/vrf_fallback_route_group_member.md index 704b9825e..57b883ef5 100644 --- a/docs/resources/vrf_fallback_route_group_member.md +++ b/docs/resources/vrf_fallback_route_group_member.md @@ -57,17 +57,19 @@ resource "aci_vrf_fallback_route_group_member" "full_example_vrf_fallback_route_ annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the VRF Fallback Route Group Member resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_vrf_fallback_route_group_member) folder. diff --git a/examples/resources/aci_communication_policy/resource-all-attributes.tf b/examples/resources/aci_communication_policy/resource-all-attributes.tf index 3f8bc491c..32094fb89 100644 --- a/examples/resources/aci_communication_policy/resource-all-attributes.tf +++ b/examples/resources/aci_communication_policy/resource-all-attributes.tf @@ -9,40 +9,90 @@ resource "aci_communication_policy" "full_example" { strict_security_on_apic_oob_subnet = "no" http_ssl_configuration = [ { - access_control_allow_credential = "disabled" - access_control_allow_origins = "access_control_allow_origins_1" - admin_st = "disabled" - annotation = "annotation_1" - cli_only_mode = "disabled" - client_cert_auth_state = "disabled" - description = "description_1" - dh_param = "1024" - global_throttle_rate = "global_throttle_rate_1" - global_throttle_st = "disabled" - global_throttle_unit = "global_throttle_unit_1" - max_request_status_count = "max_request_status_count_1" - name = "name_1" - name_alias = "name_alias_1" - node_exporter = "disabled" - port = "port_1" - referer = "referer_1" - server_header = "disabled" - ssl_protocols = "TLSv1" - throttle_rate = "throttle_rate_1" - throttle_st = "disabled" - visore_access = "disabled" + access_control_allow_credential = "access_control_allow_credential_0" + access_control_allow_origins = "access_control_allow_origins_0" + admin_st = "admin_st_0" + annotation = "annotation_0" + cli_only_mode = "cli_only_mode_0" + client_cert_auth_state = "client_cert_auth_state_0" + description = "description_0" + dh_param = "dh_param_0" + global_throttle_rate = "global_throttle_rate_0" + global_throttle_st = "global_throttle_st_0" + global_throttle_unit = "global_throttle_unit_0" + max_request_status_count = "max_request_status_count_0" + name = "name_0" + name_alias = "name_alias_0" + node_exporter = "node_exporter_0" + port = "port_0" + referer = "referer_0" + server_header = "server_header_0" + ssl_protocols = "ssl_protocols_0" + throttle_rate = "throttle_rate_0" + throttle_st = "throttle_st_0" + visore_access = "visore_access_0" + tp = [ + { + annotation = "annotation_0" + target_dn = "target_dn_0" + annotations = [ + { + key = "key_0" + value = "value_0" + } + ] + tags = [ + { + key = "key_0" + value = "value_0" + } + ] + } + ] + key_ring = [ + { + annotation = "annotation_0" + tn_pki_key_ring_name = aci_.example.name + annotations = [ + { + key = "key_0" + value = "value_0" + } + ] + tags = [ + { + key = "key_0" + value = "value_0" + } + ] + } + ] + annotations = [ + { + key = "key_0" + value = "value_0" + } + ] + tags = [ + { + key = "key_0" + value = "value_0" + } + ] } ] annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_endpoint_tag_ip/resource-all-attributes.tf b/examples/resources/aci_endpoint_tag_ip/resource-all-attributes.tf index 847c24241..15be8440a 100644 --- a/examples/resources/aci_endpoint_tag_ip/resource-all-attributes.tf +++ b/examples/resources/aci_endpoint_tag_ip/resource-all-attributes.tf @@ -10,13 +10,15 @@ resource "aci_endpoint_tag_ip" "full_example_tenant" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_endpoint_tag_mac/resource-all-attributes.tf b/examples/resources/aci_endpoint_tag_mac/resource-all-attributes.tf index cb5fcf1f3..0e05f3da5 100644 --- a/examples/resources/aci_endpoint_tag_mac/resource-all-attributes.tf +++ b/examples/resources/aci_endpoint_tag_mac/resource-all-attributes.tf @@ -10,13 +10,15 @@ resource "aci_endpoint_tag_mac" "full_example_tenant" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_external_management_network_instance_profile/resource-all-attributes.tf b/examples/resources/aci_external_management_network_instance_profile/resource-all-attributes.tf index 55b9ca15a..08fbd7ab5 100644 --- a/examples/resources/aci_external_management_network_instance_profile/resource-all-attributes.tf +++ b/examples/resources/aci_external_management_network_instance_profile/resource-all-attributes.tf @@ -7,21 +7,35 @@ resource "aci_external_management_network_instance_profile" "full_example" { priority = "level1" relation_to_consumed_out_of_band_contracts = [ { - annotation = "annotation_1" - priority = "level1" + annotation = "annotation_0" + priority = "priority_0" out_of_band_contract_name = aci_out_of_band_contract.example.name + annotations = [ + { + key = "key_0" + value = "value_0" + } + ] + tags = [ + { + key = "key_0" + value = "value_0" + } + ] } ] annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_external_management_network_subnet/resource-all-attributes.tf b/examples/resources/aci_external_management_network_subnet/resource-all-attributes.tf index 95e868212..9a61375e6 100644 --- a/examples/resources/aci_external_management_network_subnet/resource-all-attributes.tf +++ b/examples/resources/aci_external_management_network_subnet/resource-all-attributes.tf @@ -9,13 +9,15 @@ resource "aci_external_management_network_subnet" "full_example_external_managem annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_l3out_consumer_label/resource-all-attributes.tf b/examples/resources/aci_l3out_consumer_label/resource-all-attributes.tf index 09a5c84eb..0bd087084 100644 --- a/examples/resources/aci_l3out_consumer_label/resource-all-attributes.tf +++ b/examples/resources/aci_l3out_consumer_label/resource-all-attributes.tf @@ -12,13 +12,15 @@ resource "aci_l3out_consumer_label" "full_example_l3_outside" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_l3out_provider_label/resource-all-attributes.tf b/examples/resources/aci_l3out_provider_label/resource-all-attributes.tf index 25cc8e025..b148031e6 100644 --- a/examples/resources/aci_l3out_provider_label/resource-all-attributes.tf +++ b/examples/resources/aci_l3out_provider_label/resource-all-attributes.tf @@ -11,13 +11,15 @@ resource "aci_l3out_provider_label" "full_example_l3_outside" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_l3out_redistribute_policy/resource-all-attributes.tf b/examples/resources/aci_l3out_redistribute_policy/resource-all-attributes.tf index 65ac30034..bf6d6a9b3 100644 --- a/examples/resources/aci_l3out_redistribute_policy/resource-all-attributes.tf +++ b/examples/resources/aci_l3out_redistribute_policy/resource-all-attributes.tf @@ -7,13 +7,15 @@ resource "aci_l3out_redistribute_policy" "full_example_l3_outside" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_out_of_band_contract/resource-all-attributes.tf b/examples/resources/aci_out_of_band_contract/resource-all-attributes.tf index 293499941..dfd1224ba 100644 --- a/examples/resources/aci_out_of_band_contract/resource-all-attributes.tf +++ b/examples/resources/aci_out_of_band_contract/resource-all-attributes.tf @@ -13,13 +13,15 @@ resource "aci_out_of_band_contract" "full_example" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_pim_route_map_entry/resource-all-attributes.tf b/examples/resources/aci_pim_route_map_entry/resource-all-attributes.tf index c3e6636ed..108aa62a0 100644 --- a/examples/resources/aci_pim_route_map_entry/resource-all-attributes.tf +++ b/examples/resources/aci_pim_route_map_entry/resource-all-attributes.tf @@ -13,13 +13,15 @@ resource "aci_pim_route_map_entry" "full_example_pim_route_map_policy" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_pim_route_map_policy/resource-all-attributes.tf b/examples/resources/aci_pim_route_map_policy/resource-all-attributes.tf index 76766aaf0..fc24f1c92 100644 --- a/examples/resources/aci_pim_route_map_policy/resource-all-attributes.tf +++ b/examples/resources/aci_pim_route_map_policy/resource-all-attributes.tf @@ -10,13 +10,15 @@ resource "aci_pim_route_map_policy" "full_example_tenant" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_relation_to_consumed_out_of_band_contract/resource-all-attributes.tf b/examples/resources/aci_relation_to_consumed_out_of_band_contract/resource-all-attributes.tf index da51cd5a4..a9c2b98b0 100644 --- a/examples/resources/aci_relation_to_consumed_out_of_band_contract/resource-all-attributes.tf +++ b/examples/resources/aci_relation_to_consumed_out_of_band_contract/resource-all-attributes.tf @@ -7,13 +7,15 @@ resource "aci_relation_to_consumed_out_of_band_contract" "full_example_external_ annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_relation_to_fallback_route_group/resource-all-attributes.tf b/examples/resources/aci_relation_to_fallback_route_group/resource-all-attributes.tf index 34cbde73b..9f68572bb 100644 --- a/examples/resources/aci_relation_to_fallback_route_group/resource-all-attributes.tf +++ b/examples/resources/aci_relation_to_fallback_route_group/resource-all-attributes.tf @@ -6,13 +6,15 @@ resource "aci_relation_to_fallback_route_group" "full_example_l3_outside" { annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_vrf_fallback_route_group/resource-all-attributes.tf b/examples/resources/aci_vrf_fallback_route_group/resource-all-attributes.tf index b62d8fdf0..3970fc89b 100644 --- a/examples/resources/aci_vrf_fallback_route_group/resource-all-attributes.tf +++ b/examples/resources/aci_vrf_fallback_route_group/resource-all-attributes.tf @@ -7,23 +7,37 @@ resource "aci_vrf_fallback_route_group" "full_example_vrf" { name_alias = "name_alias" vrf_fallback_route_group_members = [ { - annotation = "annotation_1" - description = "description_1" - name = "name_1" - name_alias = "name_alias_1" + annotation = "annotation_0" + description = "description_0" + name = "name_0" + name_alias = "name_alias_0" fallback_member = "2.2.2.2" + annotations = [ + { + key = "key_0" + value = "value_0" + } + ] + tags = [ + { + key = "key_0" + value = "value_0" + } + ] } ] annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_vrf_fallback_route_group_member/resource-all-attributes.tf b/examples/resources/aci_vrf_fallback_route_group_member/resource-all-attributes.tf index bea43151d..051c77dfe 100644 --- a/examples/resources/aci_vrf_fallback_route_group_member/resource-all-attributes.tf +++ b/examples/resources/aci_vrf_fallback_route_group_member/resource-all-attributes.tf @@ -9,13 +9,15 @@ resource "aci_vrf_fallback_route_group_member" "full_example_vrf_fallback_route_ annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/gen/templates/resource_example_all_attributes.tf.tmpl b/gen/templates/resource_example_all_attributes.tf.tmpl index 861ed8d1a..154f67622 100644 --- a/gen/templates/resource_example_all_attributes.tf.tmpl +++ b/gen/templates/resource_example_all_attributes.tf.tmpl @@ -10,14 +10,8 @@ resource "aci_{{$.ResourceName}}" "full_example_{{getResourceName $key $.Definit {{- else}} {{overwriteProperty .PkgName .SnakeCaseName $.Definitions}} = "{{lookupTestValue .PkgName .SnakeCaseName $.TestVars $.Definitions}}" {{- end}}{{- end}} - {{- range $key, $value := $.Children}}{{$ChildResourceName := .ResourceName}} - {{$ChildResourceName}} = [ - { {{- range .Properties}}{{- if ne .NamedPropertyClass ""}} - {{overwriteProperty .PkgName .SnakeCaseName $.Definitions}} = aci_{{getResourceName .NamedPropertyClass $.Definitions}}.example.name - {{- else}} - {{overwriteProperty .PkgName .SnakeCaseName $.Definitions}} = "{{lookupChildTestValue .PkgName $ChildResourceName .SnakeCaseName $.TestVars 0 $.Definitions}}"{{- end}}{{ end}} - } - ] + {{- range $key, $value := $.Children}} + {{- template "childResourcesAndProperties" . }} {{- end}} } {{ end}} @@ -30,14 +24,23 @@ resource "aci_{{$.ResourceName}}" "full_example" { {{- else}} {{overwriteProperty .PkgName .SnakeCaseName $.Definitions}} = "{{lookupTestValue .PkgName .SnakeCaseName $.TestVars $.Definitions}}" {{- end}}{{- end}} - {{- range $key, $value := $.Children}}{{$ChildResourceName := .ResourceName}} + {{- range $key, $value := $.Children}} + {{- template "childResourcesAndProperties" . }} + {{- end}} +} +{{ end}} + +{{/* A sub template for including nested children in the examples. */}} +{{- define "childResourcesAndProperties" -}} +{{- $ChildResourceName := .ResourceName }} {{$ChildResourceName}} = [ { {{- range .Properties}}{{- if ne .NamedPropertyClass ""}} {{overwriteProperty .PkgName .SnakeCaseName $.Definitions}} = aci_{{getResourceName .NamedPropertyClass $.Definitions}}.example.name {{- else}} {{overwriteProperty .PkgName .SnakeCaseName $.Definitions}} = "{{lookupChildTestValue .PkgName $ChildResourceName .SnakeCaseName $.TestVars 0 $.Definitions}}"{{- end}}{{ end}} + {{- range $key, $value := $.Children}} + {{- template "childResourcesAndProperties" . }} + {{- end}} } ] - {{- end}} -} -{{ end}} \ No newline at end of file +{{- end}} \ No newline at end of file From 5b213a091cd18e329a931e3192b19355485f32e5 Mon Sep 17 00:00:00 2001 From: Shreyas Date: Wed, 22 May 2024 13:32:56 -0400 Subject: [PATCH 16/20] [ignore] Modified resource test template to remove child at the right index --- docs/data-sources/annotation.md | 9 - docs/data-sources/tag.md | 9 - docs/resources/annotation.md | 1 - docs/resources/l3out_node_sid_profile.md | 12 +- docs/resources/netflow_monitor_policy.md | 72 +- .../resources/relation_to_netflow_exporter.md | 12 +- docs/resources/tag.md | 1 - .../resource-all-attributes.tf | 6 +- .../resource-all-attributes.tf | 34 +- .../resource-all-attributes.tf | 6 +- gen/templates/resource_test.go.tmpl | 19 +- gen/testvars/commPol.yaml | 24 +- .../resource_aci_communication_policy_test.go | 187 ++---- ...anagement_network_instance_profile_test.go | 35 +- .../resource_aci_l3out_node_sid_profile.go | 116 +++- .../resource_aci_netflow_monitor_policy.go | 620 ++++++++++++++++-- .../resource_aci_out_of_band_contract_test.go | 22 +- ...source_aci_relation_to_netflow_exporter.go | 100 ++- 18 files changed, 930 insertions(+), 355 deletions(-) diff --git a/docs/data-sources/annotation.md b/docs/data-sources/annotation.md index 58633ce92..df8e2e982 100644 --- a/docs/data-sources/annotation.md +++ b/docs/data-sources/annotation.md @@ -73,16 +73,7 @@ data "aci_annotation" "example_application_epg" { - [aci_external_management_network_instance_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_instance_profile) ([mgmtInstP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtInstP/overview)) - [aci_relation_to_consumed_out_of_band_contract](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/relation_to_consumed_out_of_band_contract) ([mgmtRsOoBCons](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtRsOoBCons/overview)) - [aci_external_management_network_subnet](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_subnet) ([mgmtSubnet](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtSubnet/overview)) -<<<<<<< HEAD - [aci_l3out_node_sid_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/l3out_node_sid_profile) ([mplsNodeSidP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mplsNodeSidP/overview)) - - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) -======= - - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) ([pimRouteMapEntry](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapEntry/overview)) - - [aci_pim_route_map_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_policy) ([pimRouteMapPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapPol/overview)) - - [aci_route_control_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/route_control_profile) ([rtctrlProfile](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/rtctrlProfile/overview)) - - [aci_contract_interface](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/contract_interface) ([vzCPIf](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/vzCPIf/overview)) - - Too many classes to display, see model documentation for all possible classes of [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview). ->>>>>>> 1210cc50 ([ignore] Changed full identifier to parent hierarchy) * `key` (key) - (string) The key used to uniquely identify this configuration object. ### Read-Only ### diff --git a/docs/data-sources/tag.md b/docs/data-sources/tag.md index 39b977dcc..77526b15b 100644 --- a/docs/data-sources/tag.md +++ b/docs/data-sources/tag.md @@ -73,16 +73,7 @@ data "aci_tag" "example_application_epg" { - [aci_external_management_network_instance_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_instance_profile) ([mgmtInstP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtInstP/overview)) - [aci_relation_to_consumed_out_of_band_contract](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/relation_to_consumed_out_of_band_contract) ([mgmtRsOoBCons](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtRsOoBCons/overview)) - [aci_external_management_network_subnet](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_subnet) ([mgmtSubnet](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtSubnet/overview)) -<<<<<<< HEAD - [aci_l3out_node_sid_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/l3out_node_sid_profile) ([mplsNodeSidP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mplsNodeSidP/overview)) - - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) -======= - - [aci_pim_route_map_entry](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_entry) ([pimRouteMapEntry](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapEntry/overview)) - - [aci_pim_route_map_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/pim_route_map_policy) ([pimRouteMapPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/pimRouteMapPol/overview)) - - [aci_route_control_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/route_control_profile) ([rtctrlProfile](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/rtctrlProfile/overview)) - - [aci_contract_interface](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/contract_interface) ([vzCPIf](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/vzCPIf/overview)) - - Too many classes to display, see model documentation for all possible classes of [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview). ->>>>>>> 1210cc50 ([ignore] Changed full identifier to parent hierarchy) * `key` (key) - (string) The key used to uniquely identify this configuration object. ### Read-Only ### diff --git a/docs/resources/annotation.md b/docs/resources/annotation.md index 8411a91dd..0b25b2c12 100644 --- a/docs/resources/annotation.md +++ b/docs/resources/annotation.md @@ -83,7 +83,6 @@ All examples for the Annotation resource can be found in the [examples](https:// - [aci_relation_to_consumed_out_of_band_contract](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/relation_to_consumed_out_of_band_contract) ([mgmtRsOoBCons](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtRsOoBCons/overview)) - [aci_external_management_network_subnet](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_subnet) ([mgmtSubnet](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtSubnet/overview)) - [aci_l3out_node_sid_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/l3out_node_sid_profile) ([mplsNodeSidP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mplsNodeSidP/overview)) - - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. diff --git a/docs/resources/l3out_node_sid_profile.md b/docs/resources/l3out_node_sid_profile.md index bebbede6f..215620693 100644 --- a/docs/resources/l3out_node_sid_profile.md +++ b/docs/resources/l3out_node_sid_profile.md @@ -57,17 +57,19 @@ resource "aci_l3out_node_sid_profile" "full_example_l3out_loopback_interface_pro annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the L3out Node SR-MPLS Segment ID Profile resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_l3out_node_sid_profile) folder. @@ -94,14 +96,14 @@ All examples for the L3out Node SR-MPLS Segment ID Profile resource can be found * `name_alias` (nameAlias) - (string) The name alias of the L3out Node SR-MPLS Segment ID Profile object. * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -124,3 +126,5 @@ import { to = aci_l3out_node_sid_profile.example_l3out_loopback_interface_profile } ``` + + diff --git a/docs/resources/netflow_monitor_policy.md b/docs/resources/netflow_monitor_policy.md index b8fe7a861..119d46902 100644 --- a/docs/resources/netflow_monitor_policy.md +++ b/docs/resources/netflow_monitor_policy.md @@ -59,30 +59,56 @@ resource "aci_netflow_monitor_policy" "full_example_tenant" { owner_tag = "owner_tag" relation_to_netflow_exporters = [ { - annotation = "annotation_1" + annotation = "annotation_0" netflow_exporter_policy_name = aci_netflow_exporter_policy.example.name + annotations = [ + { + key = "key_0" + value = "value_0" + } + ] + tags = [ + { + key = "key_0" + value = "value_0" + } + ] } ] relation_to_netflow_record = [ { - annotation = "annotation_1" + annotation = "annotation_0" netflow_record_policy_name = aci_netflow_record_policy.example.name + annotations = [ + { + key = "key_0" + value = "value_0" + } + ] + tags = [ + { + key = "key_0" + value = "value_0" + } + ] } ] annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the Netflow Monitor Policy resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_netflow_monitor_policy) folder. @@ -113,36 +139,60 @@ All examples for the Netflow Monitor Policy resource can be found in the [exampl * `owner_tag` (ownerTag) - (string) A tag for enabling clients to add their own data. For example, to indicate who created this object. * `relation_to_netflow_exporters` - (list) A list of Relation To Netflow Exporters (ACI object [netflowRsMonitorToExporter](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowRsMonitorToExporter/overview)) pointing to Netflow Exporter Policy (ACI Object [netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) which can be configured using the [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) resource. - + #### Required #### * `netflow_exporter_policy_name` (tnNetflowExporterPolName) - (string) Name. This attribute can be referenced from a [resource](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) with `aci_netflow_exporter_policy.example.name` or from a [datasource](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/data-sources/netflow_exporter_policy) with `data.aci_netflow_exporter_policy.example.name`. - #### Optional #### * `annotation` (annotation) - (string) The annotation of the Relation To Netflow Exporter object. - Default: `orchestrator:terraform` -* `relation_to_netflow_record` - (list) A list of Relation To Netflow Record (ACI object [netflowRsMonitorToRecord](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowRsMonitorToRecord/overview)) pointing to Netflow Record Policy (ACI Object [netflowRecordPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowRecordPol/overview)) which can be configured using the [aci_netflow_record_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_record_policy) resource. + * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### - #### Required #### + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + + * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. +* `relation_to_netflow_record` - (list) A list of Relation To Netflow Record (ACI object [netflowRsMonitorToRecord](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowRsMonitorToRecord/overview)) pointing to Netflow Record Policy (ACI Object [netflowRecordPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowRecordPol/overview)) which can be configured using the [aci_netflow_record_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_record_policy) resource. + #### Optional #### * `annotation` (annotation) - (string) The annotation of the Relation To Netflow Record object. - Default: `orchestrator:terraform` * `netflow_record_policy_name` (tnNetflowRecordPolName) - (string) Name. -* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + + * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + + #### Required #### + * `key` (key) - (string) The key used to uniquely identify this configuration object. + * `value` (value) - (string) The value of the property. + +* `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -165,3 +215,5 @@ import { to = aci_netflow_monitor_policy.example_tenant } ``` + + diff --git a/docs/resources/relation_to_netflow_exporter.md b/docs/resources/relation_to_netflow_exporter.md index 4db430b13..d5533e190 100644 --- a/docs/resources/relation_to_netflow_exporter.md +++ b/docs/resources/relation_to_netflow_exporter.md @@ -56,17 +56,19 @@ resource "aci_relation_to_netflow_exporter" "full_example_netflow_monitor_policy annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + ``` All examples for the Relation To Netflow Exporter resource can be found in the [examples](https://github.com/CiscoDevNet/terraform-provider-aci/tree/master/examples/resources/aci_relation_to_netflow_exporter) folder. @@ -89,14 +91,14 @@ All examples for the Relation To Netflow Exporter resource can be found in the [ - Default: `orchestrator:terraform` * `annotations` - (list) A list of Annotations (ACI object [tagAnnotation](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagAnnotation/overview)). Annotations can also be configured using a separate [aci_annotation](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/annotation) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. * `tags` - (list) A list of Tags (ACI object [tagTag](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/tagTag/overview)). Tags can also be configured using a separate [aci_tag](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/tag) resource. This attribute is supported in ACI versions: 3.2(1l) and later. - + #### Required #### * `key` (key) - (string) The key used to uniquely identify this configuration object. @@ -119,3 +121,5 @@ import { to = aci_relation_to_netflow_exporter.example_netflow_monitor_policy } ``` + + diff --git a/docs/resources/tag.md b/docs/resources/tag.md index 366a91cf3..92bb25d15 100644 --- a/docs/resources/tag.md +++ b/docs/resources/tag.md @@ -83,7 +83,6 @@ All examples for the Tag resource can be found in the [examples](https://github. - [aci_relation_to_consumed_out_of_band_contract](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/relation_to_consumed_out_of_band_contract) ([mgmtRsOoBCons](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtRsOoBCons/overview)) - [aci_external_management_network_subnet](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/external_management_network_subnet) ([mgmtSubnet](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mgmtSubnet/overview)) - [aci_l3out_node_sid_profile](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/l3out_node_sid_profile) ([mplsNodeSidP](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/mplsNodeSidP/overview)) - - [aci_netflow_exporter_policy](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/netflow_exporter_policy) ([netflowExporterPol](https://pubhub.devnetcloud.com/media/model-doc-latest/docs/app/index.html#/objects/netflowExporterPol/overview)) * `key` (key) - (string) The key used to uniquely identify this configuration object. * `value` (value) - (string) The value of the property. diff --git a/examples/resources/aci_l3out_node_sid_profile/resource-all-attributes.tf b/examples/resources/aci_l3out_node_sid_profile/resource-all-attributes.tf index 36324de10..526d0bd72 100644 --- a/examples/resources/aci_l3out_node_sid_profile/resource-all-attributes.tf +++ b/examples/resources/aci_l3out_node_sid_profile/resource-all-attributes.tf @@ -10,13 +10,15 @@ resource "aci_l3out_node_sid_profile" "full_example_l3out_loopback_interface_pro annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_netflow_monitor_policy/resource-all-attributes.tf b/examples/resources/aci_netflow_monitor_policy/resource-all-attributes.tf index 158294f40..0e1919b92 100644 --- a/examples/resources/aci_netflow_monitor_policy/resource-all-attributes.tf +++ b/examples/resources/aci_netflow_monitor_policy/resource-all-attributes.tf @@ -9,26 +9,52 @@ resource "aci_netflow_monitor_policy" "full_example_tenant" { owner_tag = "owner_tag" relation_to_netflow_exporters = [ { - annotation = "annotation_1" + annotation = "annotation_0" netflow_exporter_policy_name = aci_netflow_exporter_policy.example.name + annotations = [ + { + key = "key_0" + value = "value_0" + } + ] + tags = [ + { + key = "key_0" + value = "value_0" + } + ] } ] relation_to_netflow_record = [ { - annotation = "annotation_1" + annotation = "annotation_0" netflow_record_policy_name = aci_netflow_record_policy.example.name + annotations = [ + { + key = "key_0" + value = "value_0" + } + ] + tags = [ + { + key = "key_0" + value = "value_0" + } + ] } ] annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/examples/resources/aci_relation_to_netflow_exporter/resource-all-attributes.tf b/examples/resources/aci_relation_to_netflow_exporter/resource-all-attributes.tf index d1063afa9..10bfd1651 100644 --- a/examples/resources/aci_relation_to_netflow_exporter/resource-all-attributes.tf +++ b/examples/resources/aci_relation_to_netflow_exporter/resource-all-attributes.tf @@ -6,13 +6,15 @@ resource "aci_relation_to_netflow_exporter" "full_example_netflow_monitor_policy annotations = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] tags = [ { key = "key_0" - value = "value_1" + value = "value_0" } ] } + + diff --git a/gen/templates/resource_test.go.tmpl b/gen/templates/resource_test.go.tmpl index 36f1a929e..f7d2d55fe 100644 --- a/gen/templates/resource_test.go.tmpl +++ b/gen/templates/resource_test.go.tmpl @@ -758,15 +758,18 @@ resource "aci_{{$.resourceName}}" "test" { {{- range $key, $value := $.resource_required}} {{$key}} = "{{$value}}" {{- end}} - {{- range $key, $value := $.children}} - {{$key}} = [ {{$child := index $value 1 }} - { - {{- range $child_key, $child_value := $child}} - {{$child_key}} = "{{$child_value}}" - {{- end}} - }, + {{- range $key, $value := $.children}} + {{$key}} = [ + {{- if gt (len $value) 1}} + {{$child := index $value 1}} + { + {{- range $child_key, $child_value := $child}} + {{$child_key}} = "{{$child_value}}" + {{- end}} + }, + {{- end}} ] - {{- end}} +{{- end}} } ` diff --git a/gen/testvars/commPol.yaml b/gen/testvars/commPol.yaml index a495f5a47..4ed33e583 100644 --- a/gen/testvars/commPol.yaml +++ b/gen/testvars/commPol.yaml @@ -51,29 +51,7 @@ children: throttle_rate: "throttle_rate_1" throttle_st: "disabled" visore_access: "disabled" - - - access_control_allow_credential: "enabled" - access_control_allow_origins: "access_control_allow_origins_2" - admin_st: "enabled" - annotation: "annotation_2" - cli_only_mode: "enabled" - client_cert_auth_state: "enabled" - description: "description_2" - dh_param: "2048" - global_throttle_rate: "global_throttle_rate_2" - global_throttle_st: "enabled" - global_throttle_unit: "global_throttle_unit_2" - max_request_status_count: "max_request_status_count_2" - name: "name_2" - name_alias: "name_alias_2" - node_exporter: "enabled" - port: "port_2" - referer: "referer_2" - server_header: "enabled" - ssl_protocols: "TLSv1.1" - throttle_rate: "throttle_rate_2" - throttle_st: "enabled" - visore_access: "enabled" + deletable_child: false annotations: - key: "key_0" diff --git a/internal/provider/resource_aci_communication_policy_test.go b/internal/provider/resource_aci_communication_policy_test.go index da7b97f6d..2e6bd24b2 100644 --- a/internal/provider/resource_aci_communication_policy_test.go +++ b/internal/provider/resource_aci_communication_policy_test.go @@ -120,28 +120,6 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.access_control_allow_credential", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.access_control_allow_origins", "access_control_allow_origins_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.admin_st", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.cli_only_mode", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.client_cert_auth_state", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.description", "description_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.dh_param", "2048"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.global_throttle_rate", "global_throttle_rate_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.global_throttle_st", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.global_throttle_unit", "global_throttle_unit_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.max_request_status_count", "max_request_status_count_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.name", "name_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.name_alias", "name_alias_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.node_exporter", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.port", "port_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.referer", "referer_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.server_header", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.ssl_protocols", "TLSv1.1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.throttle_rate", "throttle_rate_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.throttle_st", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.visore_access", "enabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "2"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.value", "value_1"), @@ -187,29 +165,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.access_control_allow_credential", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.access_control_allow_origins", "access_control_allow_origins_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.admin_st", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.cli_only_mode", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.client_cert_auth_state", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.description", "description_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.dh_param", "2048"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.global_throttle_rate", "global_throttle_rate_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.global_throttle_st", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.global_throttle_unit", "global_throttle_unit_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.max_request_status_count", "max_request_status_count_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.name", "name_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.name_alias", "name_alias_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.node_exporter", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.port", "port_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.referer", "referer_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.server_header", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.ssl_protocols", "TLSv1.1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.throttle_rate", "throttle_rate_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.throttle_st", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.1.visore_access", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "2"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.value", "value_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.1.key", "key_1"), @@ -230,28 +186,28 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.#", "1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_credential", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.dh_param", "2048"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_rate", "global_throttle_rate_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_st", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_unit", "global_throttle_unit_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.max_request_status_count", "max_request_status_count_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name", "name_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name_alias", "name_alias_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.node_exporter", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.port", "port_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.referer", "referer_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.server_header", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.ssl_protocols", "TLSv1.1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_2"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "enabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "enabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_credential", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.dh_param", "1024"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_rate", "global_throttle_rate_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_unit", "global_throttle_unit_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.max_request_status_count", "max_request_status_count_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name", "name_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name_alias", "name_alias_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.node_exporter", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.port", "port_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.referer", "referer_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.server_header", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.ssl_protocols", "TLSv1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.value", "value_2"), @@ -269,7 +225,29 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_tag", ""), resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "false"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.#", "0"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "0"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_credential", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.dh_param", "1024"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_rate", "global_throttle_rate_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_unit", "global_throttle_unit_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.max_request_status_count", "max_request_status_count_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name", "name_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name_alias", "name_alias_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.node_exporter", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.port", "port_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.referer", "referer_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.server_header", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.ssl_protocols", "TLSv1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.#", "0"), ), }, @@ -327,6 +305,7 @@ resource "aci_communication_policy" "test" { annotation = "annotation_1" cli_only_mode = "disabled" client_cert_auth_state = "disabled" + deletable_child = "false" description = "description_1" dh_param = "1024" global_throttle_rate = "global_throttle_rate_1" @@ -344,30 +323,6 @@ resource "aci_communication_policy" "test" { throttle_st = "disabled" visore_access = "disabled" }, - { - access_control_allow_credential = "enabled" - access_control_allow_origins = "access_control_allow_origins_2" - admin_st = "enabled" - annotation = "annotation_2" - cli_only_mode = "enabled" - client_cert_auth_state = "enabled" - description = "description_2" - dh_param = "2048" - global_throttle_rate = "global_throttle_rate_2" - global_throttle_st = "enabled" - global_throttle_unit = "global_throttle_unit_2" - max_request_status_count = "max_request_status_count_2" - name = "name_2" - name_alias = "name_alias_2" - node_exporter = "enabled" - port = "port_2" - referer = "referer_2" - server_header = "enabled" - ssl_protocols = "TLSv1.1" - throttle_rate = "throttle_rate_2" - throttle_st = "enabled" - visore_access = "enabled" - }, ] tags = [ { @@ -391,43 +346,21 @@ resource "aci_communication_policy" "test" { const testConfigCommPolChildrenRemoveOne = ` resource "aci_communication_policy" "test" { name = "test_name" - annotations = [ - { - key = "key_1" - value = "value_2" - }, + annotations = [ + + { + key = "key_1" + value = "value_2" + }, ] - http_ssl_configuration = [ - { - access_control_allow_credential = "enabled" - access_control_allow_origins = "access_control_allow_origins_2" - admin_st = "enabled" - annotation = "annotation_2" - cli_only_mode = "enabled" - client_cert_auth_state = "enabled" - description = "description_2" - dh_param = "2048" - global_throttle_rate = "global_throttle_rate_2" - global_throttle_st = "enabled" - global_throttle_unit = "global_throttle_unit_2" - max_request_status_count = "max_request_status_count_2" - name = "name_2" - name_alias = "name_alias_2" - node_exporter = "enabled" - port = "port_2" - referer = "referer_2" - server_header = "enabled" - ssl_protocols = "TLSv1.1" - throttle_rate = "throttle_rate_2" - throttle_st = "enabled" - visore_access = "enabled" - }, + http_ssl_configuration = [ ] - tags = [ - { - key = "key_1" - value = "value_2" - }, + tags = [ + + { + key = "key_1" + value = "value_2" + }, ] } ` diff --git a/internal/provider/resource_aci_external_management_network_instance_profile_test.go b/internal/provider/resource_aci_external_management_network_instance_profile_test.go index 32808d79d..081f139df 100644 --- a/internal/provider/resource_aci_external_management_network_instance_profile_test.go +++ b/internal/provider/resource_aci_external_management_network_instance_profile_test.go @@ -236,24 +236,27 @@ resource "aci_external_management_network_instance_profile" "test" { const testConfigMgmtInstPChildrenRemoveOne = ` resource "aci_external_management_network_instance_profile" "test" { name = "test_name" - annotations = [ - { - key = "key_1" - value = "value_2" - }, + annotations = [ + + { + key = "key_1" + value = "value_2" + }, ] - relation_to_consumed_out_of_band_contracts = [ - { - annotation = "annotation_2" - out_of_band_contract_name = "out_of_band_contract_name_1" - priority = "level2" - }, + relation_to_consumed_out_of_band_contracts = [ + + { + annotation = "annotation_2" + out_of_band_contract_name = "out_of_band_contract_name_1" + priority = "level2" + }, ] - tags = [ - { - key = "key_1" - value = "value_2" - }, + tags = [ + + { + key = "key_1" + value = "value_2" + }, ] } ` diff --git a/internal/provider/resource_aci_l3out_node_sid_profile.go b/internal/provider/resource_aci_l3out_node_sid_profile.go index b64363c56..bd77bb162 100644 --- a/internal/provider/resource_aci_l3out_node_sid_profile.go +++ b/internal/provider/resource_aci_l3out_node_sid_profile.go @@ -13,6 +13,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -59,12 +60,34 @@ type TagAnnotationMplsNodeSidPResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationMplsNodeSidPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationMplsNodeSidPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationMplsNodeSidPResourceModelAttributeTypes()) +} + // TagTagMplsNodeSidPResourceModel describes the resource data model for the children without relation ships. type TagTagMplsNodeSidPResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagMplsNodeSidPResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagMplsNodeSidPResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagMplsNodeSidPResourceModelAttributeTypes()) +} + type MplsNodeSidPIdentifier struct { Sidoffset types.String } @@ -102,6 +125,7 @@ func (r *MplsNodeSidPResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the L3out Node SR-MPLS Segment ID Profile object.`, @@ -111,6 +135,7 @@ func (r *MplsNodeSidPResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The description of the L3out Node SR-MPLS Segment ID Profile object.`, }, @@ -119,6 +144,7 @@ func (r *MplsNodeSidPResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The loopback address of the L3out Node SR-MPLS Segment ID Profile object.`, }, @@ -127,6 +153,7 @@ func (r *MplsNodeSidPResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name of the L3out Node SR-MPLS Segment ID Profile object.`, }, @@ -135,6 +162,7 @@ func (r *MplsNodeSidPResource) Schema(ctx context.Context, req resource.SchemaRe Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the L3out Node SR-MPLS Segment ID Profile object.`, }, @@ -142,6 +170,7 @@ func (r *MplsNodeSidPResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The segment ID of the L3out Node SR-MPLS Segment ID Profile object.`, @@ -159,6 +188,7 @@ func (r *MplsNodeSidPResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -166,6 +196,7 @@ func (r *MplsNodeSidPResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -185,6 +216,7 @@ func (r *MplsNodeSidPResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -192,6 +224,7 @@ func (r *MplsNodeSidPResource) Schema(ctx context.Context, req resource.SchemaRe Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -371,7 +404,7 @@ func (r *MplsNodeSidPResource) ImportState(ctx context.Context, req resource.Imp } func getAndSetMplsNodeSidPAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *MplsNodeSidPResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "mplsNodeSidP,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "mplsNodeSidP,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -404,7 +437,27 @@ func getAndSetMplsNodeSidPAttributes(ctx context.Context, diags *diag.Diagnostic data.Sidoffset = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.Descr.IsUnknown() { + data.Descr = types.StringNull() + } + if data.LoopbackAddr.IsUnknown() { + data.LoopbackAddr = types.StringNull() + } + if data.Name.IsUnknown() { + data.Name = types.StringNull() + } + if data.NameAlias.IsUnknown() { + data.NameAlias = types.StringNull() + } + if data.Sidoffset.IsUnknown() { + data.Sidoffset = types.StringNull() + } + TagAnnotationMplsNodeSidP := TagAnnotationMplsNodeSidPResourceModel{} TagAnnotationMplsNodeSidPList := make([]TagAnnotationMplsNodeSidPResourceModel, 0) + TagTagMplsNodeSidP := TagTagMplsNodeSidPResourceModel{} TagTagMplsNodeSidPList := make([]TagTagMplsNodeSidPResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -413,7 +466,6 @@ func getAndSetMplsNodeSidPAttributes(ctx context.Context, diags *diag.Diagnostic for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "tagAnnotation" { - TagAnnotationMplsNodeSidP := TagAnnotationMplsNodeSidPResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationMplsNodeSidP.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -421,11 +473,11 @@ func getAndSetMplsNodeSidPAttributes(ctx context.Context, diags *diag.Diagnostic if childAttributeName == "value" { TagAnnotationMplsNodeSidP.Value = basetypes.NewStringValue(childAttributeValue.(string)) } + } TagAnnotationMplsNodeSidPList = append(TagAnnotationMplsNodeSidPList, TagAnnotationMplsNodeSidP) } if childClassName == "tagTag" { - TagTagMplsNodeSidP := TagTagMplsNodeSidPResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagMplsNodeSidP.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -433,6 +485,7 @@ func getAndSetMplsNodeSidPAttributes(ctx context.Context, diags *diag.Diagnostic if childAttributeName == "value" { TagTagMplsNodeSidP.Value = basetypes.NewStringValue(childAttributeValue.(string)) } + } TagTagMplsNodeSidPList = append(TagTagMplsNodeSidPList, TagTagMplsNodeSidP) } @@ -485,25 +538,24 @@ func setMplsNodeSidPId(ctx context.Context, data *MplsNodeSidPResourceModel) { data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getMplsNodeSidPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MplsNodeSidPResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationMplsNodeSidPResourceModel) []map[string]interface{} { - +func getMplsNodeSidPTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MplsNodeSidPResourceModel, tagAnnotationMplsNodeSidPPlan, tagAnnotationMplsNodeSidPState []TagAnnotationMplsNodeSidPResourceModel) []map[string]interface{} { childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationMplsNodeSidP := range tagAnnotationMplsNodeSidPPlan { + childMap := NewAciObject() + if !tagAnnotationMplsNodeSidP.Key.IsNull() && !tagAnnotationMplsNodeSidP.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationMplsNodeSidP.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationMplsNodeSidP.Value.IsNull() && !tagAnnotationMplsNodeSidP.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationMplsNodeSidP.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationMplsNodeSidP.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationMplsNodeSidPState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -512,10 +564,10 @@ func getMplsNodeSidPTagAnnotationChildPayloads(ctx context.Context, diags *diag. } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -524,25 +576,25 @@ func getMplsNodeSidPTagAnnotationChildPayloads(ctx context.Context, diags *diag. return childPayloads } -func getMplsNodeSidPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MplsNodeSidPResourceModel, tagTagPlan, tagTagState []TagTagMplsNodeSidPResourceModel) []map[string]interface{} { +func getMplsNodeSidPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *MplsNodeSidPResourceModel, tagTagMplsNodeSidPPlan, tagTagMplsNodeSidPState []TagTagMplsNodeSidPResourceModel) []map[string]interface{} { childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + for _, tagTagMplsNodeSidP := range tagTagMplsNodeSidPPlan { + childMap := NewAciObject() + if !tagTagMplsNodeSidP.Key.IsNull() && !tagTagMplsNodeSidP.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagMplsNodeSidP.Key.ValueString() } - if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + if !tagTagMplsNodeSidP.Value.IsNull() && !tagTagMplsNodeSidP.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagMplsNodeSidP.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagMplsNodeSidP.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagMplsNodeSidPState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { @@ -551,10 +603,10 @@ func getMplsNodeSidPTagTagChildPayloads(ctx context.Context, diags *diag.Diagnos } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { diff --git a/internal/provider/resource_aci_netflow_monitor_policy.go b/internal/provider/resource_aci_netflow_monitor_policy.go index e3f1251a8..7e3669bbe 100644 --- a/internal/provider/resource_aci_netflow_monitor_policy.go +++ b/internal/provider/resource_aci_netflow_monitor_policy.go @@ -14,6 +14,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -61,12 +62,110 @@ type NetflowMonitorPolResourceModel struct { type NetflowRsMonitorToExporterNetflowMonitorPolResourceModel struct { Annotation types.String `tfsdk:"annotation"` TnNetflowExporterPolName types.String `tfsdk:"netflow_exporter_policy_name"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` +} + +func NetflowRsMonitorToExporterNetflowMonitorPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "annotation": types.StringType, + "netflow_exporter_policy_name": types.StringType, + "annotations": types.SetType{ElemType: TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolResourceModelElementType()}, + "tags": types.SetType{ElemType: TagTagNetflowRsMonitorToExporterNetflowMonitorPolResourceModelElementType()}, + } +} + +func NetflowRsMonitorToExporterNetflowMonitorPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, NetflowRsMonitorToExporterNetflowMonitorPolResourceModelAttributeTypes()) +} + +// TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolResourceModelAttributeTypes()) +} + +// TagTagNetflowRsMonitorToExporterNetflowMonitorPolResourceModel describes the resource data model for the children without relation ships. +type TagTagNetflowRsMonitorToExporterNetflowMonitorPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagNetflowRsMonitorToExporterNetflowMonitorPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagNetflowRsMonitorToExporterNetflowMonitorPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagNetflowRsMonitorToExporterNetflowMonitorPolResourceModelAttributeTypes()) } // NetflowRsMonitorToRecordNetflowMonitorPolResourceModel describes the resource data model for the children without relation ships. type NetflowRsMonitorToRecordNetflowMonitorPolResourceModel struct { Annotation types.String `tfsdk:"annotation"` TnNetflowRecordPolName types.String `tfsdk:"netflow_record_policy_name"` + TagAnnotation types.Set `tfsdk:"annotations"` + TagTag types.Set `tfsdk:"tags"` +} + +func NetflowRsMonitorToRecordNetflowMonitorPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "annotation": types.StringType, + "netflow_record_policy_name": types.StringType, + "annotations": types.SetType{ElemType: TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolResourceModelElementType()}, + "tags": types.SetType{ElemType: TagTagNetflowRsMonitorToRecordNetflowMonitorPolResourceModelElementType()}, + } +} + +func NetflowRsMonitorToRecordNetflowMonitorPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, NetflowRsMonitorToRecordNetflowMonitorPolResourceModelAttributeTypes()) +} + +// TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolResourceModel describes the resource data model for the children without relation ships. +type TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolResourceModelAttributeTypes()) +} + +// TagTagNetflowRsMonitorToRecordNetflowMonitorPolResourceModel describes the resource data model for the children without relation ships. +type TagTagNetflowRsMonitorToRecordNetflowMonitorPolResourceModel struct { + Key types.String `tfsdk:"key"` + Value types.String `tfsdk:"value"` +} + +func TagTagNetflowRsMonitorToRecordNetflowMonitorPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagNetflowRsMonitorToRecordNetflowMonitorPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagNetflowRsMonitorToRecordNetflowMonitorPolResourceModelAttributeTypes()) } // TagAnnotationNetflowMonitorPolResourceModel describes the resource data model for the children without relation ships. @@ -75,12 +174,34 @@ type TagAnnotationNetflowMonitorPolResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationNetflowMonitorPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationNetflowMonitorPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationNetflowMonitorPolResourceModelAttributeTypes()) +} + // TagTagNetflowMonitorPolResourceModel describes the resource data model for the children without relation ships. type TagTagNetflowMonitorPolResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagNetflowMonitorPolResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagNetflowMonitorPolResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagNetflowMonitorPolResourceModelAttributeTypes()) +} + type NetflowMonitorPolIdentifier struct { Name types.String } @@ -120,6 +241,7 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the Netflow Monitor Policy object.`, @@ -129,6 +251,7 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The description of the Netflow Monitor Policy object.`, }, @@ -136,6 +259,7 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `The name of the Netflow Monitor Policy object.`, @@ -145,6 +269,7 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The name alias of the Netflow Monitor Policy object.`, }, @@ -153,6 +278,7 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key for enabling clients to own their data for entity correlation.`, }, @@ -161,6 +287,7 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `A tag for enabling clients to add their own data. For example, to indicate who created this object.`, }, @@ -178,6 +305,7 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The annotation of the Relation To Netflow Exporter object.`, }, @@ -185,9 +313,66 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `Name.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, }, }, @@ -208,6 +393,7 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The annotation of the Relation To Netflow Record object.`, }, @@ -216,9 +402,66 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `Name.`, }, + "annotations": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, + "tags": schema.SetNestedAttribute{ + MarkdownDescription: ``, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "key": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The key used to uniquely identify this configuration object.`, + }, + "value": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), + }, + MarkdownDescription: `The value of the property.`, + }, + }, + }, + }, }, }, }, @@ -235,6 +478,7 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -242,6 +486,7 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -261,6 +506,7 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -268,6 +514,7 @@ func (r *NetflowMonitorPolResource) Schema(ctx context.Context, req resource.Sch Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -459,7 +706,7 @@ func (r *NetflowMonitorPolResource) ImportState(ctx context.Context, req resourc } func getAndSetNetflowMonitorPolAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *NetflowMonitorPolResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "netflowMonitorPol,netflowRsMonitorToExporter,netflowRsMonitorToRecord,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "netflowMonitorPol,netflowRsMonitorToExporter,netflowRsMonitorToRecord,tagAnnotation,tagTag,tagAnnotation,tagTag,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -492,9 +739,39 @@ func getAndSetNetflowMonitorPolAttributes(ctx context.Context, diags *diag.Diagn data.OwnerTag = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.Descr.IsUnknown() { + data.Descr = types.StringNull() + } + if data.Name.IsUnknown() { + data.Name = types.StringNull() + } + if data.NameAlias.IsUnknown() { + data.NameAlias = types.StringNull() + } + if data.OwnerKey.IsUnknown() { + data.OwnerKey = types.StringNull() + } + if data.OwnerTag.IsUnknown() { + data.OwnerTag = types.StringNull() + } + NetflowRsMonitorToExporterNetflowMonitorPol := NetflowRsMonitorToExporterNetflowMonitorPolResourceModel{} NetflowRsMonitorToExporterNetflowMonitorPolList := make([]NetflowRsMonitorToExporterNetflowMonitorPolResourceModel, 0) - NetflowRsMonitorToRecordNetflowMonitorPolList := make([]NetflowRsMonitorToRecordNetflowMonitorPolResourceModel, 1) + TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol := TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolResourceModel{} + TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolList := make([]TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolResourceModel, 0) + TagTagNetflowRsMonitorToExporterNetflowMonitorPol := TagTagNetflowRsMonitorToExporterNetflowMonitorPolResourceModel{} + TagTagNetflowRsMonitorToExporterNetflowMonitorPolList := make([]TagTagNetflowRsMonitorToExporterNetflowMonitorPolResourceModel, 0) + NetflowRsMonitorToRecordNetflowMonitorPol := NetflowRsMonitorToRecordNetflowMonitorPolResourceModel{} + NetflowRsMonitorToRecordNetflowMonitorPolList := make([]NetflowRsMonitorToRecordNetflowMonitorPolResourceModel, 0) + TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol := TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolResourceModel{} + TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolList := make([]TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolResourceModel, 0) + TagTagNetflowRsMonitorToRecordNetflowMonitorPol := TagTagNetflowRsMonitorToRecordNetflowMonitorPolResourceModel{} + TagTagNetflowRsMonitorToRecordNetflowMonitorPolList := make([]TagTagNetflowRsMonitorToRecordNetflowMonitorPolResourceModel, 0) + TagAnnotationNetflowMonitorPol := TagAnnotationNetflowMonitorPolResourceModel{} TagAnnotationNetflowMonitorPolList := make([]TagAnnotationNetflowMonitorPolResourceModel, 0) + TagTagNetflowMonitorPol := TagTagNetflowMonitorPolResourceModel{} TagTagNetflowMonitorPolList := make([]TagTagNetflowMonitorPolResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -503,7 +780,6 @@ func getAndSetNetflowMonitorPolAttributes(ctx context.Context, diags *diag.Diagn for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "netflowRsMonitorToExporter" { - NetflowRsMonitorToExporterNetflowMonitorPol := NetflowRsMonitorToExporterNetflowMonitorPolResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "annotation" { NetflowRsMonitorToExporterNetflowMonitorPol.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) @@ -511,11 +787,46 @@ func getAndSetNetflowMonitorPolAttributes(ctx context.Context, diags *diag.Diagn if childAttributeName == "tnNetflowExporterPolName" { NetflowRsMonitorToExporterNetflowMonitorPol.TnNetflowExporterPolName = basetypes.NewStringValue(childAttributeValue.(string)) } + + } + childrenOfNetflowRsMonitorToExporterNetflowMonitorPol, childrenOfNetflowRsMonitorToExporterNetflowMonitorPolExist := childClassDetails.(map[string]interface{})["children"] + if childrenOfNetflowRsMonitorToExporterNetflowMonitorPolExist { + for _, childNetflowRsMonitorToExporterNetflowMonitorPol := range childrenOfNetflowRsMonitorToExporterNetflowMonitorPol.([]interface{}) { + for childClassNameNetflowRsMonitorToExporterNetflowMonitorPol, childClassDetailsNetflowRsMonitorToExporterNetflowMonitorPol := range childNetflowRsMonitorToExporterNetflowMonitorPol.(map[string]interface{}) { + if childClassNameNetflowRsMonitorToExporterNetflowMonitorPol == "tagAnnotation" { + tagAnnotationchildAttributeValue := childClassDetailsNetflowRsMonitorToExporterNetflowMonitorPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { + if childAttributeName == "key" { + TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolList = append(TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolList, TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol) + } + if childClassNameNetflowRsMonitorToExporterNetflowMonitorPol == "tagTag" { + tagTagchildAttributeValue := childClassDetailsNetflowRsMonitorToExporterNetflowMonitorPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { + if childAttributeName == "key" { + TagTagNetflowRsMonitorToExporterNetflowMonitorPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagNetflowRsMonitorToExporterNetflowMonitorPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagTagNetflowRsMonitorToExporterNetflowMonitorPolList = append(TagTagNetflowRsMonitorToExporterNetflowMonitorPolList, TagTagNetflowRsMonitorToExporterNetflowMonitorPol) + } + } + } } + TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolSet, _ := types.SetValueFrom(ctx, TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolResourceModelElementType(), TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolList) + NetflowRsMonitorToExporterNetflowMonitorPol.TagAnnotation = TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolSet + TagTagNetflowRsMonitorToExporterNetflowMonitorPolSet, _ := types.SetValueFrom(ctx, TagTagNetflowRsMonitorToExporterNetflowMonitorPolResourceModelElementType(), TagTagNetflowRsMonitorToExporterNetflowMonitorPolList) + NetflowRsMonitorToExporterNetflowMonitorPol.TagTag = TagTagNetflowRsMonitorToExporterNetflowMonitorPolSet NetflowRsMonitorToExporterNetflowMonitorPolList = append(NetflowRsMonitorToExporterNetflowMonitorPolList, NetflowRsMonitorToExporterNetflowMonitorPol) } if childClassName == "netflowRsMonitorToRecord" { - NetflowRsMonitorToRecordNetflowMonitorPol := NetflowRsMonitorToRecordNetflowMonitorPolResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "annotation" { NetflowRsMonitorToRecordNetflowMonitorPol.Annotation = basetypes.NewStringValue(childAttributeValue.(string)) @@ -523,11 +834,46 @@ func getAndSetNetflowMonitorPolAttributes(ctx context.Context, diags *diag.Diagn if childAttributeName == "tnNetflowRecordPolName" { NetflowRsMonitorToRecordNetflowMonitorPol.TnNetflowRecordPolName = basetypes.NewStringValue(childAttributeValue.(string)) } + } - NetflowRsMonitorToRecordNetflowMonitorPolList[0] = NetflowRsMonitorToRecordNetflowMonitorPol + childrenOfNetflowRsMonitorToRecordNetflowMonitorPol, childrenOfNetflowRsMonitorToRecordNetflowMonitorPolExist := childClassDetails.(map[string]interface{})["children"] + if childrenOfNetflowRsMonitorToRecordNetflowMonitorPolExist { + for _, childNetflowRsMonitorToRecordNetflowMonitorPol := range childrenOfNetflowRsMonitorToRecordNetflowMonitorPol.([]interface{}) { + for childClassNameNetflowRsMonitorToRecordNetflowMonitorPol, childClassDetailsNetflowRsMonitorToRecordNetflowMonitorPol := range childNetflowRsMonitorToRecordNetflowMonitorPol.(map[string]interface{}) { + if childClassNameNetflowRsMonitorToRecordNetflowMonitorPol == "tagAnnotation" { + tagAnnotationchildAttributeValue := childClassDetailsNetflowRsMonitorToRecordNetflowMonitorPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagAnnotationchildAttributeValue { + if childAttributeName == "key" { + TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolList = append(TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolList, TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol) + } + if childClassNameNetflowRsMonitorToRecordNetflowMonitorPol == "tagTag" { + tagTagchildAttributeValue := childClassDetailsNetflowRsMonitorToRecordNetflowMonitorPol.(map[string]interface{})["attributes"].(map[string]interface{}) + for childAttributeName, childAttributeValue := range tagTagchildAttributeValue { + if childAttributeName == "key" { + TagTagNetflowRsMonitorToRecordNetflowMonitorPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) + } + if childAttributeName == "value" { + TagTagNetflowRsMonitorToRecordNetflowMonitorPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) + } + } + TagTagNetflowRsMonitorToRecordNetflowMonitorPolList = append(TagTagNetflowRsMonitorToRecordNetflowMonitorPolList, TagTagNetflowRsMonitorToRecordNetflowMonitorPol) + } + } + } + } + TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolSet, _ := types.SetValueFrom(ctx, TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolResourceModelElementType(), TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolList) + NetflowRsMonitorToRecordNetflowMonitorPol.TagAnnotation = TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolSet + TagTagNetflowRsMonitorToRecordNetflowMonitorPolSet, _ := types.SetValueFrom(ctx, TagTagNetflowRsMonitorToRecordNetflowMonitorPolResourceModelElementType(), TagTagNetflowRsMonitorToRecordNetflowMonitorPolList) + NetflowRsMonitorToRecordNetflowMonitorPol.TagTag = TagTagNetflowRsMonitorToRecordNetflowMonitorPolSet + NetflowRsMonitorToRecordNetflowMonitorPolList = append(NetflowRsMonitorToRecordNetflowMonitorPolList, NetflowRsMonitorToRecordNetflowMonitorPol) } if childClassName == "tagAnnotation" { - TagAnnotationNetflowMonitorPol := TagAnnotationNetflowMonitorPolResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationNetflowMonitorPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -535,11 +881,11 @@ func getAndSetNetflowMonitorPolAttributes(ctx context.Context, diags *diag.Diagn if childAttributeName == "value" { TagAnnotationNetflowMonitorPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) } + } TagAnnotationNetflowMonitorPolList = append(TagAnnotationNetflowMonitorPolList, TagAnnotationNetflowMonitorPol) } if childClassName == "tagTag" { - TagTagNetflowMonitorPol := TagTagNetflowMonitorPolResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagNetflowMonitorPol.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -547,6 +893,7 @@ func getAndSetNetflowMonitorPolAttributes(ctx context.Context, diags *diag.Diagn if childAttributeName == "value" { TagTagNetflowMonitorPol.Value = basetypes.NewStringValue(childAttributeValue.(string)) } + } TagTagNetflowMonitorPolList = append(TagTagNetflowMonitorPolList, TagTagNetflowMonitorPol) } @@ -603,27 +950,102 @@ func setNetflowMonitorPolId(ctx context.Context, data *NetflowMonitorPolResource data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getNetflowMonitorPolNetflowRsMonitorToExporterChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *NetflowMonitorPolResourceModel, netflowRsMonitorToExporterPlan, netflowRsMonitorToExporterState []NetflowRsMonitorToExporterNetflowMonitorPolResourceModel) []map[string]interface{} { - +func getNetflowMonitorPolNetflowRsMonitorToExporterChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *NetflowMonitorPolResourceModel, netflowRsMonitorToExporterNetflowMonitorPolPlan, netflowRsMonitorToExporterNetflowMonitorPolState []NetflowRsMonitorToExporterNetflowMonitorPolResourceModel) []map[string]interface{} { childPayloads := []map[string]interface{}{} - if !data.NetflowRsMonitorToExporter.IsUnknown() { + NetflowRsMonitorToExporterNetflowMonitorPolChildren := make([]map[string]interface{}, 0) + if !data.NetflowRsMonitorToExporter.IsNull() && !data.NetflowRsMonitorToExporter.IsUnknown() { netflowRsMonitorToExporterIdentifiers := []NetflowRsMonitorToExporterIdentifier{} - for _, netflowRsMonitorToExporter := range netflowRsMonitorToExporterPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !netflowRsMonitorToExporter.Annotation.IsUnknown() { - childMap["attributes"]["annotation"] = netflowRsMonitorToExporter.Annotation.ValueString() + for _, netflowRsMonitorToExporterNetflowMonitorPol := range netflowRsMonitorToExporterNetflowMonitorPolPlan { + childMap := NewAciObject() + if !netflowRsMonitorToExporterNetflowMonitorPol.Annotation.IsNull() && !netflowRsMonitorToExporterNetflowMonitorPol.Annotation.IsUnknown() { + childMap.Attributes["annotation"] = netflowRsMonitorToExporterNetflowMonitorPol.Annotation.ValueString() } else { - childMap["attributes"]["annotation"] = globalAnnotation + childMap.Attributes["annotation"] = globalAnnotation + } + if !netflowRsMonitorToExporterNetflowMonitorPol.TnNetflowExporterPolName.IsNull() && !netflowRsMonitorToExporterNetflowMonitorPol.TnNetflowExporterPolName.IsUnknown() { + childMap.Attributes["tnNetflowExporterPolName"] = netflowRsMonitorToExporterNetflowMonitorPol.TnNetflowExporterPolName.ValueString() + } + + var tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolPlan, tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolState []TagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolResourceModel + netflowRsMonitorToExporterNetflowMonitorPol.TagAnnotation.ElementsAs(ctx, &tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolPlan, false) + for _, tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolstate := range netflowRsMonitorToExporterNetflowMonitorPolState { + tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolstate.TagAnnotation.ElementsAs(ctx, &tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolState, false) } - if !netflowRsMonitorToExporter.TnNetflowExporterPolName.IsUnknown() { - childMap["attributes"]["tnNetflowExporterPolName"] = netflowRsMonitorToExporter.TnNetflowExporterPolName.ValueString() + if !netflowRsMonitorToExporterNetflowMonitorPol.TagAnnotation.IsNull() && !netflowRsMonitorToExporterNetflowMonitorPol.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol := range tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolPlan { + tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolChildMap := NewAciObject() + if !tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol.Key.IsNull() && !tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol.Key.IsUnknown() { + tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolChildMap.Attributes["key"] = tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol.Key.ValueString() + } + if !tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol.Value.IsNull() && !tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol.Value.IsUnknown() { + tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolChildMap.Attributes["value"] = tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol.Value.ValueString() + } + NetflowRsMonitorToExporterNetflowMonitorPolChildren = append(NetflowRsMonitorToExporterNetflowMonitorPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolChildMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol := range tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol.Key { + delete = false + break + } + } + if delete { + tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolChildMapForDelete := NewAciObject() + tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolChildMapForDelete.Attributes["key"] = tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPol.Key.ValueString() + NetflowRsMonitorToExporterNetflowMonitorPolChildren = append(NetflowRsMonitorToExporterNetflowMonitorPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationNetflowRsMonitorToExporterNetflowMonitorPolChildMapForDelete}) + } + } } + + var tagTagNetflowRsMonitorToExporterNetflowMonitorPolPlan, tagTagNetflowRsMonitorToExporterNetflowMonitorPolState []TagTagNetflowRsMonitorToExporterNetflowMonitorPolResourceModel + netflowRsMonitorToExporterNetflowMonitorPol.TagTag.ElementsAs(ctx, &tagTagNetflowRsMonitorToExporterNetflowMonitorPolPlan, false) + for _, tagTagNetflowRsMonitorToExporterNetflowMonitorPolstate := range netflowRsMonitorToExporterNetflowMonitorPolState { + tagTagNetflowRsMonitorToExporterNetflowMonitorPolstate.TagTag.ElementsAs(ctx, &tagTagNetflowRsMonitorToExporterNetflowMonitorPolState, false) + } + if !netflowRsMonitorToExporterNetflowMonitorPol.TagTag.IsNull() && !netflowRsMonitorToExporterNetflowMonitorPol.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagNetflowRsMonitorToExporterNetflowMonitorPol := range tagTagNetflowRsMonitorToExporterNetflowMonitorPolPlan { + tagTagNetflowRsMonitorToExporterNetflowMonitorPolChildMap := NewAciObject() + if !tagTagNetflowRsMonitorToExporterNetflowMonitorPol.Key.IsNull() && !tagTagNetflowRsMonitorToExporterNetflowMonitorPol.Key.IsUnknown() { + tagTagNetflowRsMonitorToExporterNetflowMonitorPolChildMap.Attributes["key"] = tagTagNetflowRsMonitorToExporterNetflowMonitorPol.Key.ValueString() + } + if !tagTagNetflowRsMonitorToExporterNetflowMonitorPol.Value.IsNull() && !tagTagNetflowRsMonitorToExporterNetflowMonitorPol.Value.IsUnknown() { + tagTagNetflowRsMonitorToExporterNetflowMonitorPolChildMap.Attributes["value"] = tagTagNetflowRsMonitorToExporterNetflowMonitorPol.Value.ValueString() + } + NetflowRsMonitorToExporterNetflowMonitorPolChildren = append(NetflowRsMonitorToExporterNetflowMonitorPolChildren, map[string]interface{}{"tagTag": tagTagNetflowRsMonitorToExporterNetflowMonitorPolChildMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagNetflowRsMonitorToExporterNetflowMonitorPol.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTagNetflowRsMonitorToExporterNetflowMonitorPol := range tagTagNetflowRsMonitorToExporterNetflowMonitorPolState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTagNetflowRsMonitorToExporterNetflowMonitorPol.Key { + delete = false + break + } + } + if delete { + tagTagNetflowRsMonitorToExporterNetflowMonitorPolChildMapForDelete := NewAciObject() + tagTagNetflowRsMonitorToExporterNetflowMonitorPolChildMapForDelete.Attributes["status"] = "deleted" + tagTagNetflowRsMonitorToExporterNetflowMonitorPolChildMapForDelete.Attributes["key"] = tagTagNetflowRsMonitorToExporterNetflowMonitorPol.Key.ValueString() + NetflowRsMonitorToExporterNetflowMonitorPolChildren = append(NetflowRsMonitorToExporterNetflowMonitorPolChildren, map[string]interface{}{"tagTag": tagTagNetflowRsMonitorToExporterNetflowMonitorPolChildMapForDelete}) + } + } + } + childMap.Children = NetflowRsMonitorToExporterNetflowMonitorPolChildren childPayloads = append(childPayloads, map[string]interface{}{"netflowRsMonitorToExporter": childMap}) netflowRsMonitorToExporterIdentifier := NetflowRsMonitorToExporterIdentifier{} - netflowRsMonitorToExporterIdentifier.TnNetflowExporterPolName = netflowRsMonitorToExporter.TnNetflowExporterPolName + netflowRsMonitorToExporterIdentifier.TnNetflowExporterPolName = netflowRsMonitorToExporterNetflowMonitorPol.TnNetflowExporterPolName netflowRsMonitorToExporterIdentifiers = append(netflowRsMonitorToExporterIdentifiers, netflowRsMonitorToExporterIdentifier) } - for _, netflowRsMonitorToExporter := range netflowRsMonitorToExporterState { + for _, netflowRsMonitorToExporter := range netflowRsMonitorToExporterNetflowMonitorPolState { delete := true for _, netflowRsMonitorToExporterIdentifier := range netflowRsMonitorToExporterIdentifiers { if netflowRsMonitorToExporterIdentifier.TnNetflowExporterPolName == netflowRsMonitorToExporter.TnNetflowExporterPolName { @@ -632,10 +1054,10 @@ func getNetflowMonitorPolNetflowRsMonitorToExporterChildPayloads(ctx context.Con } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["tnNetflowExporterPolName"] = netflowRsMonitorToExporter.TnNetflowExporterPolName.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"netflowRsMonitorToExporter": childMap}) + netflowRsMonitorToExporterChildMapForDelete := NewAciObject() + netflowRsMonitorToExporterChildMapForDelete.Attributes["status"] = "deleted" + netflowRsMonitorToExporterChildMapForDelete.Attributes["tnNetflowExporterPolName"] = netflowRsMonitorToExporter.TnNetflowExporterPolName.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"netflowRsMonitorToExporter": netflowRsMonitorToExporterChildMapForDelete}) } } } else { @@ -644,23 +1066,99 @@ func getNetflowMonitorPolNetflowRsMonitorToExporterChildPayloads(ctx context.Con return childPayloads } -func getNetflowMonitorPolNetflowRsMonitorToRecordChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *NetflowMonitorPolResourceModel, netflowRsMonitorToRecordPlan, netflowRsMonitorToRecordState []NetflowRsMonitorToRecordNetflowMonitorPolResourceModel) []map[string]interface{} { +func getNetflowMonitorPolNetflowRsMonitorToRecordChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *NetflowMonitorPolResourceModel, netflowRsMonitorToRecordNetflowMonitorPolPlan, netflowRsMonitorToRecordNetflowMonitorPolState []NetflowRsMonitorToRecordNetflowMonitorPolResourceModel) []map[string]interface{} { childPayloads := []map[string]interface{}{} - if !data.NetflowRsMonitorToRecord.IsUnknown() { - for _, netflowRsMonitorToRecord := range netflowRsMonitorToRecordPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !netflowRsMonitorToRecord.Annotation.IsUnknown() { - childMap["attributes"]["annotation"] = netflowRsMonitorToRecord.Annotation.ValueString() + NetflowRsMonitorToRecordNetflowMonitorPolChildren := make([]map[string]interface{}, 0) + if !data.NetflowRsMonitorToRecord.IsNull() && !data.NetflowRsMonitorToRecord.IsUnknown() { + for _, netflowRsMonitorToRecordNetflowMonitorPol := range netflowRsMonitorToRecordNetflowMonitorPolPlan { + childMap := NewAciObject() + if !netflowRsMonitorToRecordNetflowMonitorPol.Annotation.IsNull() && !netflowRsMonitorToRecordNetflowMonitorPol.Annotation.IsUnknown() { + childMap.Attributes["annotation"] = netflowRsMonitorToRecordNetflowMonitorPol.Annotation.ValueString() } else { - childMap["attributes"]["annotation"] = globalAnnotation + childMap.Attributes["annotation"] = globalAnnotation + } + if !netflowRsMonitorToRecordNetflowMonitorPol.TnNetflowRecordPolName.IsNull() && !netflowRsMonitorToRecordNetflowMonitorPol.TnNetflowRecordPolName.IsUnknown() { + childMap.Attributes["tnNetflowRecordPolName"] = netflowRsMonitorToRecordNetflowMonitorPol.TnNetflowRecordPolName.ValueString() + } + + var tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolPlan, tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolState []TagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolResourceModel + netflowRsMonitorToRecordNetflowMonitorPol.TagAnnotation.ElementsAs(ctx, &tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolPlan, false) + for _, tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolstate := range netflowRsMonitorToRecordNetflowMonitorPolState { + tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolstate.TagAnnotation.ElementsAs(ctx, &tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolState, false) + } + if !netflowRsMonitorToRecordNetflowMonitorPol.TagAnnotation.IsNull() && !netflowRsMonitorToRecordNetflowMonitorPol.TagAnnotation.IsUnknown() { + tagAnnotationIdentifiers := []TagAnnotationIdentifier{} + for _, tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol := range tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolPlan { + tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolChildMap := NewAciObject() + if !tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol.Key.IsNull() && !tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol.Key.IsUnknown() { + tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolChildMap.Attributes["key"] = tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol.Key.ValueString() + } + if !tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol.Value.IsNull() && !tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol.Value.IsUnknown() { + tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolChildMap.Attributes["value"] = tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol.Value.ValueString() + } + NetflowRsMonitorToRecordNetflowMonitorPolChildren = append(NetflowRsMonitorToRecordNetflowMonitorPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolChildMap}) + tagAnnotationIdentifier := TagAnnotationIdentifier{} + tagAnnotationIdentifier.Key = tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol.Key + tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) + } + for _, tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol := range tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolState { + delete := true + for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { + if tagAnnotationIdentifier.Key == tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol.Key { + delete = false + break + } + } + if delete { + tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolChildMapForDelete := NewAciObject() + tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolChildMapForDelete.Attributes["key"] = tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPol.Key.ValueString() + NetflowRsMonitorToRecordNetflowMonitorPolChildren = append(NetflowRsMonitorToRecordNetflowMonitorPolChildren, map[string]interface{}{"tagAnnotation": tagAnnotationNetflowRsMonitorToRecordNetflowMonitorPolChildMapForDelete}) + } + } + } + + var tagTagNetflowRsMonitorToRecordNetflowMonitorPolPlan, tagTagNetflowRsMonitorToRecordNetflowMonitorPolState []TagTagNetflowRsMonitorToRecordNetflowMonitorPolResourceModel + netflowRsMonitorToRecordNetflowMonitorPol.TagTag.ElementsAs(ctx, &tagTagNetflowRsMonitorToRecordNetflowMonitorPolPlan, false) + for _, tagTagNetflowRsMonitorToRecordNetflowMonitorPolstate := range netflowRsMonitorToRecordNetflowMonitorPolState { + tagTagNetflowRsMonitorToRecordNetflowMonitorPolstate.TagTag.ElementsAs(ctx, &tagTagNetflowRsMonitorToRecordNetflowMonitorPolState, false) } - if !netflowRsMonitorToRecord.TnNetflowRecordPolName.IsUnknown() { - childMap["attributes"]["tnNetflowRecordPolName"] = netflowRsMonitorToRecord.TnNetflowRecordPolName.ValueString() + if !netflowRsMonitorToRecordNetflowMonitorPol.TagTag.IsNull() && !netflowRsMonitorToRecordNetflowMonitorPol.TagTag.IsUnknown() { + tagTagIdentifiers := []TagTagIdentifier{} + for _, tagTagNetflowRsMonitorToRecordNetflowMonitorPol := range tagTagNetflowRsMonitorToRecordNetflowMonitorPolPlan { + tagTagNetflowRsMonitorToRecordNetflowMonitorPolChildMap := NewAciObject() + if !tagTagNetflowRsMonitorToRecordNetflowMonitorPol.Key.IsNull() && !tagTagNetflowRsMonitorToRecordNetflowMonitorPol.Key.IsUnknown() { + tagTagNetflowRsMonitorToRecordNetflowMonitorPolChildMap.Attributes["key"] = tagTagNetflowRsMonitorToRecordNetflowMonitorPol.Key.ValueString() + } + if !tagTagNetflowRsMonitorToRecordNetflowMonitorPol.Value.IsNull() && !tagTagNetflowRsMonitorToRecordNetflowMonitorPol.Value.IsUnknown() { + tagTagNetflowRsMonitorToRecordNetflowMonitorPolChildMap.Attributes["value"] = tagTagNetflowRsMonitorToRecordNetflowMonitorPol.Value.ValueString() + } + NetflowRsMonitorToRecordNetflowMonitorPolChildren = append(NetflowRsMonitorToRecordNetflowMonitorPolChildren, map[string]interface{}{"tagTag": tagTagNetflowRsMonitorToRecordNetflowMonitorPolChildMap}) + tagTagIdentifier := TagTagIdentifier{} + tagTagIdentifier.Key = tagTagNetflowRsMonitorToRecordNetflowMonitorPol.Key + tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) + } + for _, tagTagNetflowRsMonitorToRecordNetflowMonitorPol := range tagTagNetflowRsMonitorToRecordNetflowMonitorPolState { + delete := true + for _, tagTagIdentifier := range tagTagIdentifiers { + if tagTagIdentifier.Key == tagTagNetflowRsMonitorToRecordNetflowMonitorPol.Key { + delete = false + break + } + } + if delete { + tagTagNetflowRsMonitorToRecordNetflowMonitorPolChildMapForDelete := NewAciObject() + tagTagNetflowRsMonitorToRecordNetflowMonitorPolChildMapForDelete.Attributes["status"] = "deleted" + tagTagNetflowRsMonitorToRecordNetflowMonitorPolChildMapForDelete.Attributes["key"] = tagTagNetflowRsMonitorToRecordNetflowMonitorPol.Key.ValueString() + NetflowRsMonitorToRecordNetflowMonitorPolChildren = append(NetflowRsMonitorToRecordNetflowMonitorPolChildren, map[string]interface{}{"tagTag": tagTagNetflowRsMonitorToRecordNetflowMonitorPolChildMapForDelete}) + } + } } + childMap.Children = NetflowRsMonitorToRecordNetflowMonitorPolChildren childPayloads = append(childPayloads, map[string]interface{}{"netflowRsMonitorToRecord": childMap}) } - if len(netflowRsMonitorToRecordPlan) == 0 && len(netflowRsMonitorToRecordState) == 1 { + if len(netflowRsMonitorToRecordNetflowMonitorPolPlan) == 0 && len(netflowRsMonitorToRecordNetflowMonitorPolState) == 1 { diags.AddError( "NetflowRsMonitorToRecord object cannot be deleted", "deletion of child is only possible upon deletion of the parent", @@ -673,25 +1171,25 @@ func getNetflowMonitorPolNetflowRsMonitorToRecordChildPayloads(ctx context.Conte return childPayloads } -func getNetflowMonitorPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *NetflowMonitorPolResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationNetflowMonitorPolResourceModel) []map[string]interface{} { +func getNetflowMonitorPolTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *NetflowMonitorPolResourceModel, tagAnnotationNetflowMonitorPolPlan, tagAnnotationNetflowMonitorPolState []TagAnnotationNetflowMonitorPolResourceModel) []map[string]interface{} { childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationNetflowMonitorPol := range tagAnnotationNetflowMonitorPolPlan { + childMap := NewAciObject() + if !tagAnnotationNetflowMonitorPol.Key.IsNull() && !tagAnnotationNetflowMonitorPol.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationNetflowMonitorPol.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationNetflowMonitorPol.Value.IsNull() && !tagAnnotationNetflowMonitorPol.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationNetflowMonitorPol.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationNetflowMonitorPol.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationNetflowMonitorPolState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -700,10 +1198,10 @@ func getNetflowMonitorPolTagAnnotationChildPayloads(ctx context.Context, diags * } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -712,25 +1210,25 @@ func getNetflowMonitorPolTagAnnotationChildPayloads(ctx context.Context, diags * return childPayloads } -func getNetflowMonitorPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *NetflowMonitorPolResourceModel, tagTagPlan, tagTagState []TagTagNetflowMonitorPolResourceModel) []map[string]interface{} { +func getNetflowMonitorPolTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *NetflowMonitorPolResourceModel, tagTagNetflowMonitorPolPlan, tagTagNetflowMonitorPolState []TagTagNetflowMonitorPolResourceModel) []map[string]interface{} { childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + for _, tagTagNetflowMonitorPol := range tagTagNetflowMonitorPolPlan { + childMap := NewAciObject() + if !tagTagNetflowMonitorPol.Key.IsNull() && !tagTagNetflowMonitorPol.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagNetflowMonitorPol.Key.ValueString() } - if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + if !tagTagNetflowMonitorPol.Value.IsNull() && !tagTagNetflowMonitorPol.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagNetflowMonitorPol.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagNetflowMonitorPol.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagNetflowMonitorPolState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { @@ -739,10 +1237,10 @@ func getNetflowMonitorPolTagTagChildPayloads(ctx context.Context, diags *diag.Di } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { diff --git a/internal/provider/resource_aci_out_of_band_contract_test.go b/internal/provider/resource_aci_out_of_band_contract_test.go index baabe7f5c..45ff9312e 100644 --- a/internal/provider/resource_aci_out_of_band_contract_test.go +++ b/internal/provider/resource_aci_out_of_band_contract_test.go @@ -260,17 +260,19 @@ resource "aci_out_of_band_contract" "test" { const testConfigVzOOBBrCPChildrenRemoveOne = ` resource "aci_out_of_band_contract" "test" { name = "test_name" - annotations = [ - { - key = "key_1" - value = "value_2" - }, + annotations = [ + + { + key = "key_1" + value = "value_2" + }, ] - tags = [ - { - key = "key_1" - value = "value_2" - }, + tags = [ + + { + key = "key_1" + value = "value_2" + }, ] } ` diff --git a/internal/provider/resource_aci_relation_to_netflow_exporter.go b/internal/provider/resource_aci_relation_to_netflow_exporter.go index 858087501..79a8db827 100644 --- a/internal/provider/resource_aci_relation_to_netflow_exporter.go +++ b/internal/provider/resource_aci_relation_to_netflow_exporter.go @@ -13,6 +13,7 @@ import ( "github.com/ciscoecosystem/aci-go-client/v2/client" "github.com/ciscoecosystem/aci-go-client/v2/container" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -55,12 +56,34 @@ type TagAnnotationNetflowRsMonitorToExporterResourceModel struct { Value types.String `tfsdk:"value"` } +func TagAnnotationNetflowRsMonitorToExporterResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagAnnotationNetflowRsMonitorToExporterResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagAnnotationNetflowRsMonitorToExporterResourceModelAttributeTypes()) +} + // TagTagNetflowRsMonitorToExporterResourceModel describes the resource data model for the children without relation ships. type TagTagNetflowRsMonitorToExporterResourceModel struct { Key types.String `tfsdk:"key"` Value types.String `tfsdk:"value"` } +func TagTagNetflowRsMonitorToExporterResourceModelAttributeTypes() map[string]attr.Type { + return map[string]attr.Type{ + "key": types.StringType, + "value": types.StringType, + } +} + +func TagTagNetflowRsMonitorToExporterResourceModelElementType() attr.TypeWithAttributeTypes { + return basetypes.ObjectType.WithAttributeTypes(basetypes.ObjectType{}, TagTagNetflowRsMonitorToExporterResourceModelAttributeTypes()) +} + type NetflowRsMonitorToExporterIdentifier struct { TnNetflowExporterPolName types.String } @@ -98,6 +121,7 @@ func (r *NetflowRsMonitorToExporterResource) Schema(ctx context.Context, req res Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, Default: stringdefault.StaticString(globalAnnotation), MarkdownDescription: `The annotation of the Relation To Netflow Exporter object.`, @@ -106,6 +130,7 @@ func (r *NetflowRsMonitorToExporterResource) Schema(ctx context.Context, req res Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), stringplanmodifier.RequiresReplace(), }, MarkdownDescription: `Name.`, @@ -123,6 +148,7 @@ func (r *NetflowRsMonitorToExporterResource) Schema(ctx context.Context, req res Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -130,6 +156,7 @@ func (r *NetflowRsMonitorToExporterResource) Schema(ctx context.Context, req res Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -149,6 +176,7 @@ func (r *NetflowRsMonitorToExporterResource) Schema(ctx context.Context, req res Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The key used to uniquely identify this configuration object.`, }, @@ -156,6 +184,7 @@ func (r *NetflowRsMonitorToExporterResource) Schema(ctx context.Context, req res Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), + SetToStringNullWhenStateIsNullPlanIsUnknownDuringUpdate(), }, MarkdownDescription: `The value of the property.`, }, @@ -335,7 +364,7 @@ func (r *NetflowRsMonitorToExporterResource) ImportState(ctx context.Context, re } func getAndSetNetflowRsMonitorToExporterAttributes(ctx context.Context, diags *diag.Diagnostics, client *client.Client, data *NetflowRsMonitorToExporterResourceModel) { - requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=children&rsp-subtree-class=%s", data.Id.ValueString(), "netflowRsMonitorToExporter,tagAnnotation,tagTag"), "GET", nil) + requestData := DoRestRequest(ctx, diags, client, fmt.Sprintf("api/mo/%s.json?rsp-subtree=full&rsp-subtree-class=%s", data.Id.ValueString(), "netflowRsMonitorToExporter,tagAnnotation,tagTag"), "GET", nil) if diags.HasError() { return @@ -356,7 +385,15 @@ func getAndSetNetflowRsMonitorToExporterAttributes(ctx context.Context, diags *d data.TnNetflowExporterPolName = basetypes.NewStringValue(attributeValue.(string)) } } + if data.Annotation.IsUnknown() { + data.Annotation = types.StringNull() + } + if data.TnNetflowExporterPolName.IsUnknown() { + data.TnNetflowExporterPolName = types.StringNull() + } + TagAnnotationNetflowRsMonitorToExporter := TagAnnotationNetflowRsMonitorToExporterResourceModel{} TagAnnotationNetflowRsMonitorToExporterList := make([]TagAnnotationNetflowRsMonitorToExporterResourceModel, 0) + TagTagNetflowRsMonitorToExporter := TagTagNetflowRsMonitorToExporterResourceModel{} TagTagNetflowRsMonitorToExporterList := make([]TagTagNetflowRsMonitorToExporterResourceModel, 0) _, ok := classReadInfo[0].(map[string]interface{})["children"] if ok { @@ -365,7 +402,6 @@ func getAndSetNetflowRsMonitorToExporterAttributes(ctx context.Context, diags *d for childClassName, childClassDetails := range child.(map[string]interface{}) { childAttributes := childClassDetails.(map[string]interface{})["attributes"].(map[string]interface{}) if childClassName == "tagAnnotation" { - TagAnnotationNetflowRsMonitorToExporter := TagAnnotationNetflowRsMonitorToExporterResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagAnnotationNetflowRsMonitorToExporter.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -373,11 +409,11 @@ func getAndSetNetflowRsMonitorToExporterAttributes(ctx context.Context, diags *d if childAttributeName == "value" { TagAnnotationNetflowRsMonitorToExporter.Value = basetypes.NewStringValue(childAttributeValue.(string)) } + } TagAnnotationNetflowRsMonitorToExporterList = append(TagAnnotationNetflowRsMonitorToExporterList, TagAnnotationNetflowRsMonitorToExporter) } if childClassName == "tagTag" { - TagTagNetflowRsMonitorToExporter := TagTagNetflowRsMonitorToExporterResourceModel{} for childAttributeName, childAttributeValue := range childAttributes { if childAttributeName == "key" { TagTagNetflowRsMonitorToExporter.Key = basetypes.NewStringValue(childAttributeValue.(string)) @@ -385,6 +421,7 @@ func getAndSetNetflowRsMonitorToExporterAttributes(ctx context.Context, diags *d if childAttributeName == "value" { TagTagNetflowRsMonitorToExporter.Value = basetypes.NewStringValue(childAttributeValue.(string)) } + } TagTagNetflowRsMonitorToExporterList = append(TagTagNetflowRsMonitorToExporterList, TagTagNetflowRsMonitorToExporter) } @@ -437,25 +474,24 @@ func setNetflowRsMonitorToExporterId(ctx context.Context, data *NetflowRsMonitor data.Id = types.StringValue(fmt.Sprintf("%s/%s", data.ParentDn.ValueString(), rn)) } -func getNetflowRsMonitorToExporterTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *NetflowRsMonitorToExporterResourceModel, tagAnnotationPlan, tagAnnotationState []TagAnnotationNetflowRsMonitorToExporterResourceModel) []map[string]interface{} { - +func getNetflowRsMonitorToExporterTagAnnotationChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *NetflowRsMonitorToExporterResourceModel, tagAnnotationNetflowRsMonitorToExporterPlan, tagAnnotationNetflowRsMonitorToExporterState []TagAnnotationNetflowRsMonitorToExporterResourceModel) []map[string]interface{} { childPayloads := []map[string]interface{}{} - if !data.TagAnnotation.IsUnknown() { + if !data.TagAnnotation.IsNull() && !data.TagAnnotation.IsUnknown() { tagAnnotationIdentifiers := []TagAnnotationIdentifier{} - for _, tagAnnotation := range tagAnnotationPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !tagAnnotation.Key.IsUnknown() { - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() + for _, tagAnnotationNetflowRsMonitorToExporter := range tagAnnotationNetflowRsMonitorToExporterPlan { + childMap := NewAciObject() + if !tagAnnotationNetflowRsMonitorToExporter.Key.IsNull() && !tagAnnotationNetflowRsMonitorToExporter.Key.IsUnknown() { + childMap.Attributes["key"] = tagAnnotationNetflowRsMonitorToExporter.Key.ValueString() } - if !tagAnnotation.Value.IsUnknown() { - childMap["attributes"]["value"] = tagAnnotation.Value.ValueString() + if !tagAnnotationNetflowRsMonitorToExporter.Value.IsNull() && !tagAnnotationNetflowRsMonitorToExporter.Value.IsUnknown() { + childMap.Attributes["value"] = tagAnnotationNetflowRsMonitorToExporter.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) tagAnnotationIdentifier := TagAnnotationIdentifier{} - tagAnnotationIdentifier.Key = tagAnnotation.Key + tagAnnotationIdentifier.Key = tagAnnotationNetflowRsMonitorToExporter.Key tagAnnotationIdentifiers = append(tagAnnotationIdentifiers, tagAnnotationIdentifier) } - for _, tagAnnotation := range tagAnnotationState { + for _, tagAnnotation := range tagAnnotationNetflowRsMonitorToExporterState { delete := true for _, tagAnnotationIdentifier := range tagAnnotationIdentifiers { if tagAnnotationIdentifier.Key == tagAnnotation.Key { @@ -464,10 +500,10 @@ func getNetflowRsMonitorToExporterTagAnnotationChildPayloads(ctx context.Context } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagAnnotation.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": childMap}) + tagAnnotationChildMapForDelete := NewAciObject() + tagAnnotationChildMapForDelete.Attributes["status"] = "deleted" + tagAnnotationChildMapForDelete.Attributes["key"] = tagAnnotation.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagAnnotation": tagAnnotationChildMapForDelete}) } } } else { @@ -476,25 +512,25 @@ func getNetflowRsMonitorToExporterTagAnnotationChildPayloads(ctx context.Context return childPayloads } -func getNetflowRsMonitorToExporterTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *NetflowRsMonitorToExporterResourceModel, tagTagPlan, tagTagState []TagTagNetflowRsMonitorToExporterResourceModel) []map[string]interface{} { +func getNetflowRsMonitorToExporterTagTagChildPayloads(ctx context.Context, diags *diag.Diagnostics, data *NetflowRsMonitorToExporterResourceModel, tagTagNetflowRsMonitorToExporterPlan, tagTagNetflowRsMonitorToExporterState []TagTagNetflowRsMonitorToExporterResourceModel) []map[string]interface{} { childPayloads := []map[string]interface{}{} - if !data.TagTag.IsUnknown() { + if !data.TagTag.IsNull() && !data.TagTag.IsUnknown() { tagTagIdentifiers := []TagTagIdentifier{} - for _, tagTag := range tagTagPlan { - childMap := map[string]map[string]interface{}{"attributes": {}} - if !tagTag.Key.IsUnknown() { - childMap["attributes"]["key"] = tagTag.Key.ValueString() + for _, tagTagNetflowRsMonitorToExporter := range tagTagNetflowRsMonitorToExporterPlan { + childMap := NewAciObject() + if !tagTagNetflowRsMonitorToExporter.Key.IsNull() && !tagTagNetflowRsMonitorToExporter.Key.IsUnknown() { + childMap.Attributes["key"] = tagTagNetflowRsMonitorToExporter.Key.ValueString() } - if !tagTag.Value.IsUnknown() { - childMap["attributes"]["value"] = tagTag.Value.ValueString() + if !tagTagNetflowRsMonitorToExporter.Value.IsNull() && !tagTagNetflowRsMonitorToExporter.Value.IsUnknown() { + childMap.Attributes["value"] = tagTagNetflowRsMonitorToExporter.Value.ValueString() } childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) tagTagIdentifier := TagTagIdentifier{} - tagTagIdentifier.Key = tagTag.Key + tagTagIdentifier.Key = tagTagNetflowRsMonitorToExporter.Key tagTagIdentifiers = append(tagTagIdentifiers, tagTagIdentifier) } - for _, tagTag := range tagTagState { + for _, tagTag := range tagTagNetflowRsMonitorToExporterState { delete := true for _, tagTagIdentifier := range tagTagIdentifiers { if tagTagIdentifier.Key == tagTag.Key { @@ -503,10 +539,10 @@ func getNetflowRsMonitorToExporterTagTagChildPayloads(ctx context.Context, diags } } if delete { - childMap := map[string]map[string]interface{}{"attributes": {}} - childMap["attributes"]["status"] = "deleted" - childMap["attributes"]["key"] = tagTag.Key.ValueString() - childPayloads = append(childPayloads, map[string]interface{}{"tagTag": childMap}) + tagTagChildMapForDelete := NewAciObject() + tagTagChildMapForDelete.Attributes["status"] = "deleted" + tagTagChildMapForDelete.Attributes["key"] = tagTag.Key.ValueString() + childPayloads = append(childPayloads, map[string]interface{}{"tagTag": tagTagChildMapForDelete}) } } } else { From 2146e83d66aeb730f78aef28973e58be2355d63f Mon Sep 17 00:00:00 2001 From: Shreyas Date: Fri, 7 Jun 2024 08:35:05 -0400 Subject: [PATCH 17/20] [ignore] Added recursive sub templates in testvars.yml to accommodate nested children --- gen/generator.go | 2 +- gen/templates/testvars.yaml.tmpl | 47 ++++++++++------ gen/testvars/commPol.yaml | 54 +++++++++++++++++++ gen/testvars/fvEpIpTag.yaml | 3 ++ gen/testvars/fvEpMacTag.yaml | 3 ++ gen/testvars/fvFBRGroup.yaml | 17 ++++++ gen/testvars/fvFBRMember.yaml | 3 ++ gen/testvars/l3extConsLbl.yaml | 3 ++ gen/testvars/l3extProvLbl.yaml | 3 ++ gen/testvars/l3extRsOutToFBRGroup.yaml | 3 ++ gen/testvars/l3extRsRedistributePol.yaml | 3 ++ gen/testvars/mgmtInstP.yaml | 17 ++++++ gen/testvars/mgmtRsOoBCons.yaml | 3 ++ gen/testvars/mgmtSubnet.yaml | 3 ++ gen/testvars/mplsNodeSidP.yaml | 3 ++ gen/testvars/netflowMonitorPol.yaml | 31 +++++++++++ gen/testvars/netflowRsMonitorToExporter.yaml | 3 ++ gen/testvars/pimRouteMapEntry.yaml | 3 ++ gen/testvars/pimRouteMapPol.yaml | 3 ++ gen/testvars/tagAnnotation.yaml | 3 ++ gen/testvars/tagTag.yaml | 3 ++ gen/testvars/vzOOBBrCP.yaml | 3 ++ .../resource_aci_communication_policy_test.go | 20 +++++++ ...anagement_network_instance_profile_test.go | 10 ++++ ...esource_aci_netflow_monitor_policy_test.go | 24 +++++++++ ...ource_aci_vrf_fallback_route_group_test.go | 12 +++++ 26 files changed, 266 insertions(+), 16 deletions(-) diff --git a/gen/generator.go b/gen/generator.go index b0689ef08..4057cf0e0 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -624,7 +624,7 @@ func main() { renderTemplate("testvars.yaml.tmpl", fmt.Sprintf("%s.yaml", model.PkgName), testVarsPath, model) testVarsMap, err := getTestVars(model) if err != nil { - panic(err) + panic(model.PkgName) } model.TestVars = testVarsMap renderTemplate("resource.go.tmpl", fmt.Sprintf("resource_%s_%s.go", providerName, model.ResourceName), providerPath, model) diff --git a/gen/templates/testvars.yaml.tmpl b/gen/templates/testvars.yaml.tmpl index fc638fd13..ef98f9b9f 100644 --- a/gen/templates/testvars.yaml.tmpl +++ b/gen/templates/testvars.yaml.tmpl @@ -53,21 +53,10 @@ all: {{- end}} {{ if .Children}} children: - {{- range $key, $value := .Children}}{{$name := .ResourceName}}{{$child_deletable := .AllowDelete}} - {{.ResourceName}}: - {{- if not .IdentifiedBy}} - - {{ range .Properties}}{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}: {{$length := len .ValidValues}}{{if ne $length 0}}"{{ index .ValidValues 0 }}"{{else if not .IsNaming}}"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}_1"{{- else}}"{{lookupChildTestValue .PkgName $.ResourceName .SnakeCaseName $.TestVars 0 $.Definitions}}"{{- end}} - {{ end}} - {{- if $child_deletable -}} - deletable_child: true - {{- else -}} - deletable_child: false - {{ end}} - {{- else}} - - {{ range .Properties}}{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}: {{$length := len .ValidValues}}{{if ne $length 0}}"{{ index .ValidValues 0 }}"{{else if not .IsNaming}}"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}_1"{{- else}}"{{lookupChildTestValue .PkgName $.ResourceName .SnakeCaseName $.TestVars 0 $.Definitions}}"{{- end}} - {{ end}} - - {{ range .Properties}}{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}: {{$length := len .ValidValues}}{{if ge $length 2}}"{{ index .ValidValues 1 }}"{{else if not .IsNaming}}"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}_2"{{- else}}"{{lookupChildTestValue .PkgName $.ResourceName .SnakeCaseName $.TestVars 1 $.Definitions}}"{{- end}} - {{ end}}{{- end}}{{- end}}{{- end}} + {{- range $key, $value := .Children}} + {{- $newCtx := addToTemplateProperties . "Indent" "" -}} + {{- template "nestedChildren" $newCtx }} + {{- end}}{{- end}} {{- if .ContainedBy}} parents: {{- $index := 0}}{{- range $key := .DocumentationExamples}}{{$parentDependency := getParentTestDependencies $.PkgName $index $.Definitions}} @@ -104,3 +93,31 @@ targets: {{- end}}{{$index = add $index 1}} {{- end }} {{- end}} + + +{{/* A sub template for including vars in nested children. */}} +{{- define "nestedChildren" -}} +{{- $indent := .TemplateProperties.Indent -}} +{{$name := .ResourceName}}{{$child_deletable := .AllowDelete}} + {{ $indent }}{{.ResourceName}}: + {{- if not .IdentifiedBy}} + {{- $enteredPropertiesZone := false }} + {{ $indent }}- {{ range .Properties}}{{- if $enteredPropertiesZone }}{{ $indent }}{{- else}}{{- $enteredPropertiesZone = true }}{{- end}}{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}: {{$length := len .ValidValues}}{{if ne $length 0}}"{{ index .ValidValues 0 }}"{{else if not .IsNaming}}"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}_1"{{- else}}"{{lookupChildTestValue .PkgName $.ResourceName .SnakeCaseName $.TestVars 0 $.Definitions}}"{{- end}} + {{ end}} + {{- if $child_deletable -}} + {{ $indent }}deletable_child: true + {{- else -}} + {{ $indent }}deletable_child: false + {{ end}} + {{- else}} + {{- $enteredPropertiesZone1 := false }} + {{ $indent }}- {{ range .Properties}}{{- if $enteredPropertiesZone1 }}{{ $indent }}{{- else}}{{- $enteredPropertiesZone1 = true }}{{- end}}{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}: {{$length := len .ValidValues}}{{if ne $length 0}}"{{ index .ValidValues 0 }}"{{else if not .IsNaming}}"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}_1"{{- else}}"{{lookupChildTestValue .PkgName $.ResourceName .SnakeCaseName $.TestVars 0 $.Definitions}}"{{- end}} + {{ end}} + {{- $enteredPropertiesZone2 := false }} + {{ $indent }}- {{ range .Properties}}{{- if $enteredPropertiesZone2 }}{{ $indent }}{{- else}}{{- $enteredPropertiesZone2 = true }}{{- end}}{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}: {{$length := len .ValidValues}}{{if ge $length 2}}"{{ index .ValidValues 1 }}"{{else if not .IsNaming}}"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}_2"{{- else}}"{{lookupChildTestValue .PkgName $.ResourceName .SnakeCaseName $.TestVars 1 $.Definitions}}"{{- end}} + {{ end}}{{- end}} + {{- range $key, $value := .Children}} + {{- $newCtx := addToTemplateProperties . "Indent" (print $indent " ") -}} + {{- template "nestedChildren" $newCtx }} + {{- end}} + {{- end}} diff --git a/gen/testvars/commPol.yaml b/gen/testvars/commPol.yaml index 4ed33e583..f173657d0 100644 --- a/gen/testvars/commPol.yaml +++ b/gen/testvars/commPol.yaml @@ -53,6 +53,57 @@ children: visore_access: "disabled" deletable_child: false + tp: + - annotation: "annotation_1" + target_dn: "target_dn_1" + deletable_child: true + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + key_ring: + - annotation: "annotation_1" + tn_pki_key_ring_name: "tn_pki_key_ring_name_1" + deletable_child: false + + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + annotations: - key: "key_0" value: "value_1" @@ -67,3 +118,6 @@ children: - key: "key_1" value: "value_2" + + + diff --git a/gen/testvars/fvEpIpTag.yaml b/gen/testvars/fvEpIpTag.yaml index 07b6c2485..ddf3a5b44 100644 --- a/gen/testvars/fvEpIpTag.yaml +++ b/gen/testvars/fvEpIpTag.yaml @@ -46,3 +46,6 @@ parents: parent_dependency: "" parent_dn: "aci_tenant.test.id" class_in_parent: false + + + diff --git a/gen/testvars/fvEpMacTag.yaml b/gen/testvars/fvEpMacTag.yaml index 5c4298d7f..d86a849d4 100644 --- a/gen/testvars/fvEpMacTag.yaml +++ b/gen/testvars/fvEpMacTag.yaml @@ -46,3 +46,6 @@ parents: parent_dependency: "" parent_dn: "aci_tenant.test.id" class_in_parent: false + + + diff --git a/gen/testvars/fvFBRGroup.yaml b/gen/testvars/fvFBRGroup.yaml index 8fd06febd..3cd00c1ab 100644 --- a/gen/testvars/fvFBRGroup.yaml +++ b/gen/testvars/fvFBRGroup.yaml @@ -35,6 +35,20 @@ children: name_alias: "name_alias_2" fallback_member: "2.2.2.3" + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + annotations: - key: "key_0" value: "value_1" @@ -54,3 +68,6 @@ parents: parent_dependency: "fvTenant" parent_dn: "aci_vrf.test.id" class_in_parent: false + + + diff --git a/gen/testvars/fvFBRMember.yaml b/gen/testvars/fvFBRMember.yaml index 218e652f2..2e5ab882f 100644 --- a/gen/testvars/fvFBRMember.yaml +++ b/gen/testvars/fvFBRMember.yaml @@ -43,3 +43,6 @@ parents: parent_dependency: "fvCtx" parent_dn: "aci_vrf_fallback_route_group.test.id" class_in_parent: false + + + diff --git a/gen/testvars/l3extConsLbl.yaml b/gen/testvars/l3extConsLbl.yaml index fabbd89ac..fa89a9f82 100644 --- a/gen/testvars/l3extConsLbl.yaml +++ b/gen/testvars/l3extConsLbl.yaml @@ -49,3 +49,6 @@ parents: parent_dependency: "" parent_dn: "aci_l3_outside.test.id" class_in_parent: false + + + diff --git a/gen/testvars/l3extProvLbl.yaml b/gen/testvars/l3extProvLbl.yaml index b43254708..cf5d6be02 100644 --- a/gen/testvars/l3extProvLbl.yaml +++ b/gen/testvars/l3extProvLbl.yaml @@ -48,3 +48,6 @@ parents: parent_dn: "aci_l3_outside.test.id" class_in_parent: false parent_dependency_name: "infra" + + + diff --git a/gen/testvars/l3extRsOutToFBRGroup.yaml b/gen/testvars/l3extRsOutToFBRGroup.yaml index 12a6716b9..4aa03a0ed 100644 --- a/gen/testvars/l3extRsOutToFBRGroup.yaml +++ b/gen/testvars/l3extRsOutToFBRGroup.yaml @@ -46,3 +46,6 @@ targets: parent_dependency_dn: "aci_vrf.test.id" resource_required: name: "fallback_route_group" + + + diff --git a/gen/testvars/l3extRsRedistributePol.yaml b/gen/testvars/l3extRsRedistributePol.yaml index fcd38f5b5..775eb2974 100644 --- a/gen/testvars/l3extRsRedistributePol.yaml +++ b/gen/testvars/l3extRsRedistributePol.yaml @@ -42,3 +42,6 @@ parents: parent_dependency: "fvTenant" parent_dn: "aci_l3_outside.test.id" class_in_parent: true + + + diff --git a/gen/testvars/mgmtInstP.yaml b/gen/testvars/mgmtInstP.yaml index a2c1874a2..d175b8a21 100644 --- a/gen/testvars/mgmtInstP.yaml +++ b/gen/testvars/mgmtInstP.yaml @@ -33,6 +33,20 @@ children: priority: "level2" out_of_band_contract_name: "out_of_band_contract_name_1" + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + annotations: - key: "key_0" value: "value_1" @@ -47,3 +61,6 @@ children: - key: "key_1" value: "value_2" + + + diff --git a/gen/testvars/mgmtRsOoBCons.yaml b/gen/testvars/mgmtRsOoBCons.yaml index 301687bba..cc689e5c0 100644 --- a/gen/testvars/mgmtRsOoBCons.yaml +++ b/gen/testvars/mgmtRsOoBCons.yaml @@ -39,3 +39,6 @@ parents: parent_dependency: "" parent_dn: "aci_external_management_network_instance_profile.test.id" class_in_parent: false + + + diff --git a/gen/testvars/mgmtSubnet.yaml b/gen/testvars/mgmtSubnet.yaml index b7280633a..034b37134 100644 --- a/gen/testvars/mgmtSubnet.yaml +++ b/gen/testvars/mgmtSubnet.yaml @@ -43,3 +43,6 @@ parents: parent_dependency: "" parent_dn: "aci_external_management_network_instance_profile.test.id" class_in_parent: false + + + diff --git a/gen/testvars/mplsNodeSidP.yaml b/gen/testvars/mplsNodeSidP.yaml index 90659625c..7c5473c56 100644 --- a/gen/testvars/mplsNodeSidP.yaml +++ b/gen/testvars/mplsNodeSidP.yaml @@ -45,3 +45,6 @@ parents: parent_dependency: "l3extRsNodeL3OutAtt" parent_dn: "aci_l3out_loopback_interface_profile.test.id" class_in_parent: false + + + diff --git a/gen/testvars/netflowMonitorPol.yaml b/gen/testvars/netflowMonitorPol.yaml index 1c9b59842..178194bed 100644 --- a/gen/testvars/netflowMonitorPol.yaml +++ b/gen/testvars/netflowMonitorPol.yaml @@ -33,11 +33,39 @@ children: - annotation: "annotation_2" netflow_exporter_policy_name: "netflow_exporter_policy_name_1" + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + relation_to_netflow_record: - annotation: "annotation_1" netflow_record_policy_name: "netflow_record_policy_name_1" deletable_child: false + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + annotations: - key: "key_0" value: "value_1" @@ -57,3 +85,6 @@ parents: parent_dependency: "" parent_dn: "aci_tenant.test.id" class_in_parent: false + + + diff --git a/gen/testvars/netflowRsMonitorToExporter.yaml b/gen/testvars/netflowRsMonitorToExporter.yaml index 68ab8e82b..d429e297f 100644 --- a/gen/testvars/netflowRsMonitorToExporter.yaml +++ b/gen/testvars/netflowRsMonitorToExporter.yaml @@ -37,3 +37,6 @@ parents: parent_dependency: "fvTenant" parent_dn: "aci_netflow_monitor_policy.test.id" class_in_parent: false + + + diff --git a/gen/testvars/pimRouteMapEntry.yaml b/gen/testvars/pimRouteMapEntry.yaml index bfdfb090d..4b4d055d9 100644 --- a/gen/testvars/pimRouteMapEntry.yaml +++ b/gen/testvars/pimRouteMapEntry.yaml @@ -51,3 +51,6 @@ parents: parent_dependency: "fvTenant" parent_dn: "aci_pim_route_map_policy.test.id" class_in_parent: false + + + diff --git a/gen/testvars/pimRouteMapPol.yaml b/gen/testvars/pimRouteMapPol.yaml index cac7fd60c..560c67e84 100644 --- a/gen/testvars/pimRouteMapPol.yaml +++ b/gen/testvars/pimRouteMapPol.yaml @@ -45,3 +45,6 @@ parents: parent_dependency: "" parent_dn: "aci_tenant.test.id" class_in_parent: false + + + diff --git a/gen/testvars/tagAnnotation.yaml b/gen/testvars/tagAnnotation.yaml index be258afb5..fc77b635a 100644 --- a/gen/testvars/tagAnnotation.yaml +++ b/gen/testvars/tagAnnotation.yaml @@ -27,3 +27,6 @@ parents: parent_dependency: "" parent_dn: "aci_application_epg.test.id" class_in_parent: false + + + diff --git a/gen/testvars/tagTag.yaml b/gen/testvars/tagTag.yaml index be258afb5..fc77b635a 100644 --- a/gen/testvars/tagTag.yaml +++ b/gen/testvars/tagTag.yaml @@ -27,3 +27,6 @@ parents: parent_dependency: "" parent_dn: "aci_application_epg.test.id" class_in_parent: false + + + diff --git a/gen/testvars/vzOOBBrCP.yaml b/gen/testvars/vzOOBBrCP.yaml index 2c6696909..4c6d23c3f 100644 --- a/gen/testvars/vzOOBBrCP.yaml +++ b/gen/testvars/vzOOBBrCP.yaml @@ -48,3 +48,6 @@ children: - key: "key_1" value: "value_2" + + + diff --git a/internal/provider/resource_aci_communication_policy_test.go b/internal/provider/resource_aci_communication_policy_test.go index 2e6bd24b2..b0ab82e65 100644 --- a/internal/provider/resource_aci_communication_policy_test.go +++ b/internal/provider/resource_aci_communication_policy_test.go @@ -102,6 +102,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), @@ -109,6 +110,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_rate", "global_throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_unit", "global_throttle_unit_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.key_ring", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:false tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tn_pki_key_ring_name:tn_pki_key_ring_name_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.max_request_status_count", "max_request_status_count_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name", "name_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name_alias", "name_alias_1"), @@ -117,8 +119,10 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.referer", "referer_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.server_header", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.ssl_protocols", "TLSv1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tp", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:true tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] target_dn:target_dn_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "2"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "key_0"), @@ -147,6 +151,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), @@ -154,6 +159,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_rate", "global_throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_unit", "global_throttle_unit_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.key_ring", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:false tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tn_pki_key_ring_name:tn_pki_key_ring_name_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.max_request_status_count", "max_request_status_count_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name", "name_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name_alias", "name_alias_1"), @@ -162,8 +168,10 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.referer", "referer_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.server_header", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.ssl_protocols", "TLSv1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tp", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:true tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] target_dn:target_dn_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "key_0"), @@ -190,6 +198,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), @@ -197,6 +206,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_rate", "global_throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_unit", "global_throttle_unit_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.key_ring", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:false tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tn_pki_key_ring_name:tn_pki_key_ring_name_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.max_request_status_count", "max_request_status_count_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name", "name_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name_alias", "name_alias_1"), @@ -205,8 +215,10 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.referer", "referer_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.server_header", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.ssl_protocols", "TLSv1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tp", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:true tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] target_dn:target_dn_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "key_1"), @@ -229,6 +241,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), @@ -236,6 +249,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_rate", "global_throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_unit", "global_throttle_unit_1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.key_ring", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:false tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tn_pki_key_ring_name:tn_pki_key_ring_name_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.max_request_status_count", "max_request_status_count_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name", "name_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name_alias", "name_alias_1"), @@ -244,8 +258,10 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.referer", "referer_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.server_header", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.ssl_protocols", "TLSv1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tp", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:true tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] target_dn:target_dn_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.#", "0"), @@ -303,6 +319,7 @@ resource "aci_communication_policy" "test" { access_control_allow_origins = "access_control_allow_origins_1" admin_st = "disabled" annotation = "annotation_1" + annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" cli_only_mode = "disabled" client_cert_auth_state = "disabled" deletable_child = "false" @@ -311,6 +328,7 @@ resource "aci_communication_policy" "test" { global_throttle_rate = "global_throttle_rate_1" global_throttle_st = "disabled" global_throttle_unit = "global_throttle_unit_1" + key_ring = "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:false tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tn_pki_key_ring_name:tn_pki_key_ring_name_1]]" max_request_status_count = "max_request_status_count_1" name = "name_1" name_alias = "name_alias_1" @@ -319,8 +337,10 @@ resource "aci_communication_policy" "test" { referer = "referer_1" server_header = "disabled" ssl_protocols = "TLSv1" + tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" throttle_rate = "throttle_rate_1" throttle_st = "disabled" + tp = "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:true tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] target_dn:target_dn_1]]" visore_access = "disabled" }, ] diff --git a/internal/provider/resource_aci_external_management_network_instance_profile_test.go b/internal/provider/resource_aci_external_management_network_instance_profile_test.go index 081f139df..bcace679c 100644 --- a/internal/provider/resource_aci_external_management_network_instance_profile_test.go +++ b/internal/provider/resource_aci_external_management_network_instance_profile_test.go @@ -90,8 +90,10 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.annotation", "annotation_2"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.priority", "level2"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.value", "value_1"), @@ -117,8 +119,10 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.annotation", "annotation_2"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.priority", "level2"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.value", "value_1"), @@ -139,8 +143,10 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.#", "1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.annotation", "annotation_2"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level2"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.value", "value_2"), @@ -210,8 +216,10 @@ resource "aci_external_management_network_instance_profile" "test" { }, { annotation = "annotation_2" + annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" out_of_band_contract_name = "out_of_band_contract_name_1" priority = "level2" + tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" }, ] tags = [ @@ -247,8 +255,10 @@ resource "aci_external_management_network_instance_profile" "test" { { annotation = "annotation_2" + annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" out_of_band_contract_name = "out_of_band_contract_name_1" priority = "level2" + tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" }, ] tags = [ diff --git a/internal/provider/resource_aci_netflow_monitor_policy_test.go b/internal/provider/resource_aci_netflow_monitor_policy_test.go index 1c5fae7a0..4e28adc60 100644 --- a/internal/provider/resource_aci_netflow_monitor_policy_test.go +++ b/internal/provider/resource_aci_netflow_monitor_policy_test.go @@ -95,9 +95,13 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.netflow_exporter_policy_name", "netflow_exporter_policy_name_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotation", "annotation_2"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.netflow_exporter_policy_name", "netflow_exporter_policy_name_1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.value", "value_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.1.key", "key_1"), @@ -123,9 +127,13 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.netflow_exporter_policy_name", "netflow_exporter_policy_name_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotation", "annotation_2"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.netflow_exporter_policy_name", "netflow_exporter_policy_name_1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.value", "value_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.1.key", "key_1"), @@ -145,10 +153,14 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.netflow_exporter_policy_name", "netflow_exporter_policy_name_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotation", "annotation_2"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.netflow_exporter_policy_name", "netflow_exporter_policy_name_1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.#", "2"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.#", "1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.value", "value_1"), @@ -166,10 +178,14 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "annotations.#", "1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.annotation", "annotation_2"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.netflow_exporter_policy_name", "netflow_exporter_policy_name_1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.#", "1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.#", "1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.value", "value_2"), @@ -184,7 +200,9 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "annotations.#", "0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.#", "0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.#", "1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.#", "0"), ), @@ -244,13 +262,17 @@ resource "aci_netflow_monitor_policy" "test" { }, { annotation = "annotation_2" + annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" netflow_exporter_policy_name = "netflow_exporter_policy_name_1" + tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" }, ] relation_to_netflow_record = [ { annotation = "annotation_1" + annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" netflow_record_policy_name = "netflow_record_policy_name_1" + tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" }, ] tags = [ @@ -286,7 +308,9 @@ resource "aci_netflow_monitor_policy" "test" { relation_to_netflow_exporters = [ { annotation = "annotation_2" + annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" netflow_exporter_policy_name = "netflow_exporter_policy_name_1" + tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" }, ] tags = [ diff --git a/internal/provider/resource_aci_vrf_fallback_route_group_test.go b/internal/provider/resource_aci_vrf_fallback_route_group_test.go index 9978f34be..290f6ccc7 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group_test.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group_test.go @@ -92,10 +92,12 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name", "name_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name_alias", "name_alias_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotation", "annotation_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.description", "description_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.fallback_member", "2.2.2.3"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name", "name_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name_alias", "name_alias_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), ), }, // Import testing with children @@ -122,10 +124,12 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name", "name_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name_alias", "name_alias_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotation", "annotation_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.description", "description_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.fallback_member", "2.2.2.3"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name", "name_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name_alias", "name_alias_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), ), }, // Update with children removed from config @@ -149,10 +153,12 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name", "name_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name_alias", "name_alias_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotation", "annotation_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.description", "description_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.fallback_member", "2.2.2.3"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name", "name_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name_alias", "name_alias_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.#", "2"), ), }, @@ -168,10 +174,12 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.#", "1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.annotation", "annotation_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.description", "description_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.fallback_member", "2.2.2.3"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name", "name_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name_alias", "name_alias_2"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.#", "1"), ), }, @@ -249,10 +257,12 @@ resource "aci_vrf_fallback_route_group" "test" { }, { annotation = "annotation_2" + annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" description = "description_2" fallback_member = "2.2.2.3" name = "name_2" name_alias = "name_alias_2" + tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" }, ] } @@ -284,10 +294,12 @@ resource "aci_vrf_fallback_route_group" "test" { vrf_fallback_route_group_members = [ { annotation = "annotation_2" + annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" description = "description_2" fallback_member = "2.2.2.3" name = "name_2" name_alias = "name_alias_2" + tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" }, ] } From 5b3eaaf3cdc8e56e53349b2a936872011380e28c Mon Sep 17 00:00:00 2001 From: Shreyas Date: Mon, 10 Jun 2024 18:36:59 -0400 Subject: [PATCH 18/20] [ignore] Added children identifier in testvars for nested children --- gen/generator.go | 34 +++++- gen/templates/resource_test.go.tmpl | 29 ++++- gen/templates/testvars.yaml.tmpl | 9 +- gen/testvars/commPol.yaml | 103 +++++++++--------- gen/testvars/fvFBRGroup.yaml | 21 ++-- gen/testvars/mgmtInstP.yaml | 21 ++-- gen/testvars/netflowMonitorPol.yaml | 42 +++---- .../resource_aci_communication_policy_test.go | 97 +++++++++++++---- ...anagement_network_instance_profile_test.go | 34 ++++-- ...esource_aci_netflow_monitor_policy_test.go | 36 ++---- ...ource_aci_vrf_fallback_route_group_test.go | 18 +-- 11 files changed, 280 insertions(+), 164 deletions(-) diff --git a/gen/generator.go b/gen/generator.go index 4057cf0e0..0cdd442d1 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -105,6 +105,7 @@ var templateFuncs = template.FuncMap{ "lowerFirstCharacter": LowerFirstCharacter, "isListEmpty": func(stringList []string) bool { return len(stringList) == 0 }, "addToTemplateProperties": AddToTemplateProperties, + "addToChild": AddToChildInTestTemplate, } // Global variables used for unique resource name setting based on label from meta data @@ -252,7 +253,7 @@ func DictForTemplates(values ...interface{}) (map[string]interface{}, error) { return dict, nil } -// AddToTemplate creates a copy of the context with the new fields provided in the form of key value pairs +// AddToTemplateProperties creates a copy of the model and updates it with the new fields provided in the form of key value pairs func AddToTemplateProperties(model Model, values ...interface{}) (*Model, error) { // Create a copy of the model newModel := model @@ -265,9 +266,6 @@ func AddToTemplateProperties(model Model, values ...interface{}) (*Model, error) newModel.TemplateProperties = make(map[string]interface{}) } - for k, v := range newModel.TemplateProperties { - newModel.TemplateProperties[k] = v - } for k, v := range updates { newModel.TemplateProperties[k] = v } @@ -275,6 +273,32 @@ func AddToTemplateProperties(model Model, values ...interface{}) (*Model, error) return &newModel, nil } +// AddToChildInTestTemplate is used within the test templates for applying indentation in the test config +func AddToChildInTestTemplate(child map[interface{}]interface{}, values ...interface{}) (map[interface{}]interface{}, error) { + + newChild := make(map[interface{}]interface{}) + childValue := make(map[interface{}]interface{}) + for k, v := range child { + childValue[k] = v + } + newChild["childValue"] = childValue + + updates, err := DictForTemplates(values...) + if err != nil { + return nil, err + } + + if _, ok := newChild["TemplateProperties"]; !ok { + newChild["TemplateProperties"] = make(map[string]interface{}) + } + + for k, v := range updates { + newChild["TemplateProperties"].(map[string]interface{})[k] = v + } + + return newChild, nil +} + // Renders the templates and writes a file to the output directory func renderTemplate(templateName, outputFileName, outputPath string, outputData interface{}) { templateData, err := os.ReadFile(fmt.Sprintf("%s/%s", templatePath, templateName)) @@ -624,7 +648,7 @@ func main() { renderTemplate("testvars.yaml.tmpl", fmt.Sprintf("%s.yaml", model.PkgName), testVarsPath, model) testVarsMap, err := getTestVars(model) if err != nil { - panic(model.PkgName) + panic(err) } model.TestVars = testVarsMap renderTemplate("resource.go.tmpl", fmt.Sprintf("resource_%s_%s.go", providerName, model.ResourceName), providerPath, model) diff --git a/gen/templates/resource_test.go.tmpl b/gen/templates/resource_test.go.tmpl index f7d2d55fe..789be270b 100644 --- a/gen/templates/resource_test.go.tmpl +++ b/gen/templates/resource_test.go.tmpl @@ -736,8 +736,13 @@ resource "aci_{{$.resourceName}}" "test" { {{- range $child := $value}} { {{- range $child_key, $child_value := $child}} + {{- if eq $child_key "children"}} + {{- $newCtx := addToChild $child_value "Indent" " " -}} + {{- template "nestedChildren" $newCtx }} + {{- else if ne $child_key "deletable_child"}} {{$child_key}} = "{{$child_value}}" - {{- end}} + {{- end}} + {{- end}} }, {{- end}} ] @@ -785,4 +790,26 @@ resource "aci_{{$.resourceName}}" "test" { ` {{- end}} +{{- end}} + + +{{/* A sub template for including nested children. */}} +{{- define "nestedChildren" -}} + {{- $indent := .TemplateProperties.Indent -}} + {{- range $key, $value := .childValue}} + {{$indent}}{{$key}} = [ + {{- range $child := $value}} + {{$indent}}{ + {{- range $child_key, $child_value := $child}} + {{- if eq $child_key "children"}} + {{- $newCtx := addToChild $child_value "Indent" (print $indent " ") -}} + {{- template "nestedChildren" $newCtx }} + {{- else if ne $child_key "deletable_child"}} + {{$indent}}{{$child_key}} = "{{$child_value}}" + {{- end}} + {{- end}} + {{$indent}}}, + {{- end}} + {{$indent}}] +{{- end}} {{- end}} \ No newline at end of file diff --git a/gen/templates/testvars.yaml.tmpl b/gen/templates/testvars.yaml.tmpl index ef98f9b9f..95ae78494 100644 --- a/gen/templates/testvars.yaml.tmpl +++ b/gen/templates/testvars.yaml.tmpl @@ -116,8 +116,15 @@ targets: {{- $enteredPropertiesZone2 := false }} {{ $indent }}- {{ range .Properties}}{{- if $enteredPropertiesZone2 }}{{ $indent }}{{- else}}{{- $enteredPropertiesZone2 = true }}{{- end}}{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}: {{$length := len .ValidValues}}{{if ge $length 2}}"{{ index .ValidValues 1 }}"{{else if not .IsNaming}}"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}_2"{{- else}}"{{lookupChildTestValue .PkgName $.ResourceName .SnakeCaseName $.TestVars 1 $.Definitions}}"{{- end}} {{ end}}{{- end}} + {{- $enteredGrandChildZone := false }} + {{- range .Children}} + {{- if not $enteredGrandChildZone }} + {{- $enteredGrandChildZone = true }} + {{ $indent }}children: + {{- end }} + {{- end }} {{- range $key, $value := .Children}} - {{- $newCtx := addToTemplateProperties . "Indent" (print $indent " ") -}} + {{- $newCtx := addToTemplateProperties . "Indent" (print $indent " ") -}} {{- template "nestedChildren" $newCtx }} {{- end}} {{- end}} diff --git a/gen/testvars/commPol.yaml b/gen/testvars/commPol.yaml index f173657d0..e2ef9c941 100644 --- a/gen/testvars/commPol.yaml +++ b/gen/testvars/commPol.yaml @@ -53,56 +53,59 @@ children: visore_access: "disabled" deletable_child: false - tp: - - annotation: "annotation_1" - target_dn: "target_dn_1" - deletable_child: true - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - key_ring: - - annotation: "annotation_1" - tn_pki_key_ring_name: "tn_pki_key_ring_name_1" - deletable_child: false - - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - annotations: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" - - tags: - - key: "key_0" - value: "value_1" - - - key: "key_1" - value: "value_2" + children: + tp: + - annotation: "annotation_1" + target_dn: "target_dn_1" + deletable_child: true + children: + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + key_ring: + - annotation: "annotation_1" + tn_pki_key_ring_name: "tn_pki_key_ring_name_1" + deletable_child: false + + children: + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + annotations: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" + + tags: + - key: "key_0" + value: "value_1" + + - key: "key_1" + value: "value_2" annotations: - key: "key_0" diff --git a/gen/testvars/fvFBRGroup.yaml b/gen/testvars/fvFBRGroup.yaml index 3cd00c1ab..d76ad44a4 100644 --- a/gen/testvars/fvFBRGroup.yaml +++ b/gen/testvars/fvFBRGroup.yaml @@ -35,19 +35,20 @@ children: name_alias: "name_alias_2" fallback_member: "2.2.2.3" - annotations: - - key: "key_0" - value: "value_1" + children: + annotations: + - key: "key_0" + value: "value_1" - - key: "key_1" - value: "value_2" + - key: "key_1" + value: "value_2" - tags: - - key: "key_0" - value: "value_1" + tags: + - key: "key_0" + value: "value_1" - - key: "key_1" - value: "value_2" + - key: "key_1" + value: "value_2" annotations: - key: "key_0" diff --git a/gen/testvars/mgmtInstP.yaml b/gen/testvars/mgmtInstP.yaml index d175b8a21..559715152 100644 --- a/gen/testvars/mgmtInstP.yaml +++ b/gen/testvars/mgmtInstP.yaml @@ -33,19 +33,20 @@ children: priority: "level2" out_of_band_contract_name: "out_of_band_contract_name_1" - annotations: - - key: "key_0" - value: "value_1" + children: + annotations: + - key: "key_0" + value: "value_1" - - key: "key_1" - value: "value_2" + - key: "key_1" + value: "value_2" - tags: - - key: "key_0" - value: "value_1" + tags: + - key: "key_0" + value: "value_1" - - key: "key_1" - value: "value_2" + - key: "key_1" + value: "value_2" annotations: - key: "key_0" diff --git a/gen/testvars/netflowMonitorPol.yaml b/gen/testvars/netflowMonitorPol.yaml index 178194bed..37f9e3a02 100644 --- a/gen/testvars/netflowMonitorPol.yaml +++ b/gen/testvars/netflowMonitorPol.yaml @@ -33,38 +33,40 @@ children: - annotation: "annotation_2" netflow_exporter_policy_name: "netflow_exporter_policy_name_1" - annotations: - - key: "key_0" - value: "value_1" + children: + annotations: + - key: "key_0" + value: "value_1" - - key: "key_1" - value: "value_2" + - key: "key_1" + value: "value_2" - tags: - - key: "key_0" - value: "value_1" + tags: + - key: "key_0" + value: "value_1" - - key: "key_1" - value: "value_2" + - key: "key_1" + value: "value_2" relation_to_netflow_record: - annotation: "annotation_1" netflow_record_policy_name: "netflow_record_policy_name_1" deletable_child: false - annotations: - - key: "key_0" - value: "value_1" + children: + annotations: + - key: "key_0" + value: "value_1" - - key: "key_1" - value: "value_2" + - key: "key_1" + value: "value_2" - tags: - - key: "key_0" - value: "value_1" + tags: + - key: "key_0" + value: "value_1" - - key: "key_1" - value: "value_2" + - key: "key_1" + value: "value_2" annotations: - key: "key_0" diff --git a/internal/provider/resource_aci_communication_policy_test.go b/internal/provider/resource_aci_communication_policy_test.go index b0ab82e65..6d49e19e6 100644 --- a/internal/provider/resource_aci_communication_policy_test.go +++ b/internal/provider/resource_aci_communication_policy_test.go @@ -102,7 +102,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] key_ring:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:false tn_pki_key_ring_name:tn_pki_key_ring_name_1]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tp:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:true target_dn:target_dn_1]]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), @@ -110,7 +110,6 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_rate", "global_throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_unit", "global_throttle_unit_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.key_ring", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:false tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tn_pki_key_ring_name:tn_pki_key_ring_name_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.max_request_status_count", "max_request_status_count_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name", "name_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name_alias", "name_alias_1"), @@ -119,10 +118,8 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.referer", "referer_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.server_header", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.ssl_protocols", "TLSv1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tp", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:true tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] target_dn:target_dn_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "2"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "key_0"), @@ -151,7 +148,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] key_ring:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:false tn_pki_key_ring_name:tn_pki_key_ring_name_1]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tp:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:true target_dn:target_dn_1]]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), @@ -159,7 +156,6 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_rate", "global_throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_unit", "global_throttle_unit_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.key_ring", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:false tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tn_pki_key_ring_name:tn_pki_key_ring_name_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.max_request_status_count", "max_request_status_count_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name", "name_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name_alias", "name_alias_1"), @@ -168,10 +164,8 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.referer", "referer_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.server_header", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.ssl_protocols", "TLSv1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tp", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:true tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] target_dn:target_dn_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "key_0"), @@ -198,7 +192,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] key_ring:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:false tn_pki_key_ring_name:tn_pki_key_ring_name_1]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tp:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:true target_dn:target_dn_1]]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), @@ -206,7 +200,6 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_rate", "global_throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_unit", "global_throttle_unit_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.key_ring", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:false tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tn_pki_key_ring_name:tn_pki_key_ring_name_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.max_request_status_count", "max_request_status_count_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name", "name_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name_alias", "name_alias_1"), @@ -215,10 +208,8 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.referer", "referer_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.server_header", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.ssl_protocols", "TLSv1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tp", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:true tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] target_dn:target_dn_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "key_1"), @@ -241,7 +232,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] key_ring:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:false tn_pki_key_ring_name:tn_pki_key_ring_name_1]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tp:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:true target_dn:target_dn_1]]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), @@ -249,7 +240,6 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_rate", "global_throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.global_throttle_unit", "global_throttle_unit_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.key_ring", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:false tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tn_pki_key_ring_name:tn_pki_key_ring_name_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.max_request_status_count", "max_request_status_count_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name", "name_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.name_alias", "name_alias_1"), @@ -258,10 +248,8 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.referer", "referer_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.server_header", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.ssl_protocols", "TLSv1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_rate", "throttle_rate_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.tp", "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:true tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] target_dn:target_dn_1]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.#", "0"), @@ -319,16 +307,85 @@ resource "aci_communication_policy" "test" { access_control_allow_origins = "access_control_allow_origins_1" admin_st = "disabled" annotation = "annotation_1" - annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + key_ring = [ + { + annotation = "annotation_1" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tn_pki_key_ring_name = "tn_pki_key_ring_name_1" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tp = [ + { + annotation = "annotation_1" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + target_dn = "target_dn_1" + }, + ] cli_only_mode = "disabled" client_cert_auth_state = "disabled" - deletable_child = "false" description = "description_1" dh_param = "1024" global_throttle_rate = "global_throttle_rate_1" global_throttle_st = "disabled" global_throttle_unit = "global_throttle_unit_1" - key_ring = "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:false tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tn_pki_key_ring_name:tn_pki_key_ring_name_1]]" max_request_status_count = "max_request_status_count_1" name = "name_1" name_alias = "name_alias_1" @@ -337,10 +394,8 @@ resource "aci_communication_policy" "test" { referer = "referer_1" server_header = "disabled" ssl_protocols = "TLSv1" - tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" throttle_rate = "throttle_rate_1" throttle_st = "disabled" - tp = "[map[annotation:annotation_1 annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] deletable_child:true tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] target_dn:target_dn_1]]" visore_access = "disabled" }, ] diff --git a/internal/provider/resource_aci_external_management_network_instance_profile_test.go b/internal/provider/resource_aci_external_management_network_instance_profile_test.go index bcace679c..521e16644 100644 --- a/internal/provider/resource_aci_external_management_network_instance_profile_test.go +++ b/internal/provider/resource_aci_external_management_network_instance_profile_test.go @@ -90,10 +90,9 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.priority", "level2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.value", "value_1"), @@ -119,10 +118,9 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.priority", "level2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.value", "value_1"), @@ -143,10 +141,9 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.#", "1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.value", "value_2"), @@ -216,10 +213,28 @@ resource "aci_external_management_network_instance_profile" "test" { }, { annotation = "annotation_2" - annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] out_of_band_contract_name = "out_of_band_contract_name_1" priority = "level2" - tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" }, ] tags = [ @@ -255,10 +270,9 @@ resource "aci_external_management_network_instance_profile" "test" { { annotation = "annotation_2" - annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" + children = "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]" out_of_band_contract_name = "out_of_band_contract_name_1" priority = "level2" - tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" }, ] tags = [ diff --git a/internal/provider/resource_aci_netflow_monitor_policy_test.go b/internal/provider/resource_aci_netflow_monitor_policy_test.go index 4e28adc60..586f5f195 100644 --- a/internal/provider/resource_aci_netflow_monitor_policy_test.go +++ b/internal/provider/resource_aci_netflow_monitor_policy_test.go @@ -95,13 +95,11 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.netflow_exporter_policy_name", "netflow_exporter_policy_name_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.netflow_exporter_policy_name", "netflow_exporter_policy_name_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.value", "value_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.1.key", "key_1"), @@ -127,13 +125,11 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.netflow_exporter_policy_name", "netflow_exporter_policy_name_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.netflow_exporter_policy_name", "netflow_exporter_policy_name_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.value", "value_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.1.key", "key_1"), @@ -153,14 +149,12 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.netflow_exporter_policy_name", "netflow_exporter_policy_name_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.netflow_exporter_policy_name", "netflow_exporter_policy_name_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.#", "2"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.#", "1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.value", "value_1"), @@ -178,14 +172,12 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "annotations.#", "1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.netflow_exporter_policy_name", "netflow_exporter_policy_name_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.#", "1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.#", "1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.value", "value_2"), @@ -200,9 +192,8 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "annotations.#", "0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.#", "0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.#", "1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.#", "0"), ), @@ -262,17 +253,15 @@ resource "aci_netflow_monitor_policy" "test" { }, { annotation = "annotation_2" - annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" + children = "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]" netflow_exporter_policy_name = "netflow_exporter_policy_name_1" - tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" }, ] relation_to_netflow_record = [ { annotation = "annotation_1" - annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" + children = "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]" netflow_record_policy_name = "netflow_record_policy_name_1" - tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" }, ] tags = [ @@ -308,9 +297,8 @@ resource "aci_netflow_monitor_policy" "test" { relation_to_netflow_exporters = [ { annotation = "annotation_2" - annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" + children = "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]" netflow_exporter_policy_name = "netflow_exporter_policy_name_1" - tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" }, ] tags = [ diff --git a/internal/provider/resource_aci_vrf_fallback_route_group_test.go b/internal/provider/resource_aci_vrf_fallback_route_group_test.go index 290f6ccc7..aff4e0ed0 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group_test.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group_test.go @@ -92,12 +92,11 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name", "name_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name_alias", "name_alias_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.description", "description_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.fallback_member", "2.2.2.3"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name", "name_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name_alias", "name_alias_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), ), }, // Import testing with children @@ -124,12 +123,11 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name", "name_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name_alias", "name_alias_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.description", "description_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.fallback_member", "2.2.2.3"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name", "name_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name_alias", "name_alias_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), ), }, // Update with children removed from config @@ -153,12 +151,11 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name", "name_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name_alias", "name_alias_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.description", "description_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.fallback_member", "2.2.2.3"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name", "name_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name_alias", "name_alias_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.#", "2"), ), }, @@ -174,12 +171,11 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.#", "1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.annotations", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.description", "description_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.fallback_member", "2.2.2.3"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name", "name_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name_alias", "name_alias_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.tags", "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.#", "1"), ), }, @@ -257,12 +253,11 @@ resource "aci_vrf_fallback_route_group" "test" { }, { annotation = "annotation_2" - annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" + children = "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]" description = "description_2" fallback_member = "2.2.2.3" name = "name_2" name_alias = "name_alias_2" - tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" }, ] } @@ -294,12 +289,11 @@ resource "aci_vrf_fallback_route_group" "test" { vrf_fallback_route_group_members = [ { annotation = "annotation_2" - annotations = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" + children = "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]" description = "description_2" fallback_member = "2.2.2.3" name = "name_2" name_alias = "name_alias_2" - tags = "[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]" }, ] } From f16ca884cb10d3e063fbceac0248ae9293e6bd78 Mon Sep 17 00:00:00 2001 From: Shreyas Date: Thu, 20 Jun 2024 18:21:52 -0400 Subject: [PATCH 19/20] [ignore] Addition of recursive sub-templates for removing one child and all children if they deletable --- gen/templates/resource_test.go.tmpl | 134 ++++++++++++++---- gen/templates/testvars.yaml.tmpl | 13 +- gen/testvars/commPol.yaml | 32 ++--- gen/testvars/fvEpIpTag.yaml | 8 +- gen/testvars/fvEpMacTag.yaml | 8 +- gen/testvars/fvFBRGroup.yaml | 20 +-- gen/testvars/fvFBRMember.yaml | 8 +- gen/testvars/l3extConsLbl.yaml | 8 +- gen/testvars/l3extProvLbl.yaml | 8 +- gen/testvars/l3extRsOutToFBRGroup.yaml | 8 +- gen/testvars/l3extRsRedistributePol.yaml | 8 +- gen/testvars/mgmtInstP.yaml | 20 +-- gen/testvars/mgmtRsOoBCons.yaml | 8 +- gen/testvars/mgmtSubnet.yaml | 8 +- gen/testvars/mplsNodeSidP.yaml | 8 +- gen/testvars/netflowMonitorPol.yaml | 28 ++-- gen/testvars/netflowRsMonitorToExporter.yaml | 8 +- gen/testvars/pimRouteMapEntry.yaml | 8 +- gen/testvars/pimRouteMapPol.yaml | 8 +- gen/testvars/vzOOBBrCP.yaml | 8 +- .../resource_aci_communication_policy_test.go | 125 ++++++++++++++-- .../resource_aci_endpoint_tag_ip_test.go | 20 +-- .../resource_aci_endpoint_tag_mac_test.go | 20 +-- ...anagement_network_instance_profile_test.go | 48 ++++--- ...external_management_network_subnet_test.go | 20 +-- .../resource_aci_l3out_consumer_label_test.go | 20 +-- ...esource_aci_l3out_node_sid_profile_test.go | 20 +-- .../resource_aci_l3out_provider_label_test.go | 20 +-- ...urce_aci_l3out_redistribute_policy_test.go | 20 +-- ...esource_aci_netflow_monitor_policy_test.go | 131 +++++++++++++---- .../resource_aci_out_of_band_contract_test.go | 18 +-- .../resource_aci_pim_route_map_entry_test.go | 20 +-- .../resource_aci_pim_route_map_policy_test.go | 20 +-- ...n_to_consumed_out_of_band_contract_test.go | 20 +-- ...i_relation_to_fallback_route_group_test.go | 20 +-- ...e_aci_relation_to_netflow_exporter_test.go | 20 +-- ...ci_vrf_fallback_route_group_member_test.go | 20 +-- ...ource_aci_vrf_fallback_route_group_test.go | 72 +++++++--- 38 files changed, 695 insertions(+), 318 deletions(-) diff --git a/gen/templates/resource_test.go.tmpl b/gen/templates/resource_test.go.tmpl index 789be270b..b0a05ee5a 100644 --- a/gen/templates/resource_test.go.tmpl +++ b/gen/templates/resource_test.go.tmpl @@ -613,7 +613,10 @@ resource "aci_{{$.resourceName}}" "test" { {{- range $child := $value}} { {{- range $child_key, $child_value := $child}} - {{- if ne $child_key "deletable_child"}} + {{- if eq $child_key "children"}} + {{- $newCtx := addToChild $child_value "Indent" " " -}} + {{- template "nestedChildren" $newCtx }} + {{- else if ne $child_key "deletable_child"}} {{$child_key}} = "{{$child_value}}" {{- end}} {{- end}} @@ -648,21 +651,23 @@ resource "aci_{{$.resourceName}}" "test" { {{- end }} {{- end}} {{- range $key, $value := $.children}} - {{- if eq (len $value) 1}} - {{- $child := index $value 0}} - {{- if $child.deletable_child}} - {{$key}} = [] - {{- end}} - {{- else}} - {{$key}} = [ {{$child := index $value 1 }} - { - {{- range $child_key, $child_value := $child}} + {{$key}} = [ + {{- range $index, $child := $value}} + {{- if or (ne $index 0) (and (eq $index 0) (not $child.deletable_child)) }} + { + {{- range $child_key, $child_value := $child}} + {{- if eq $child_key "children"}} + {{- $newCtx := addToChild $child_value "Indent" " " -}} + {{- template "nestedChildrenRemoveOne" $newCtx }} + {{- else if ne $child_key "deletable_child"}} {{$child_key}} = "{{$child_value}}" {{- end}} - }, + {{- end}} + }, + {{- end}} + {{- end}} ] - {{- end}} - {{- end}} +{{- end}} } ` @@ -677,15 +682,23 @@ resource "aci_{{$.resourceName}}" "test" { {{- end }} {{- end}} {{- range $key, $value := $.children}} - {{- if eq (len $value) 1}} - {{- $child := index $value 0}} - {{- if $child.deletable_child}} - {{$key}} = [] - {{- end}} - {{- else}} - {{$key}} = [] + {{$key}} = [ + {{- range $index, $child := $value}} + {{- if not $child.deletable_child }} + { + {{- range $child_key, $child_value := $child}} + {{- if eq $child_key "children"}} + {{- $newCtx := addToChild $child_value "Indent" " " -}} + {{- template "nestedChildrenRemoveAll" $newCtx }} + {{- else if ne $child_key "deletable_child"}} + {{$child_key}} = "{{$child_value}}" {{- end}} - {{- end}} + {{- end}} + }, + {{- end}} + {{- end}} + ] + {{- end}} } ` {{- end}} @@ -765,14 +778,20 @@ resource "aci_{{$.resourceName}}" "test" { {{- end}} {{- range $key, $value := $.children}} {{$key}} = [ - {{- if gt (len $value) 1}} - {{$child := index $value 1}} + {{- range $index, $child := $value}} + {{- if or (ne $index 0) (and (eq $index 0) (not $child.deletable_child)) }} { {{- range $child_key, $child_value := $child}} - {{$child_key}} = "{{$child_value}}" + {{- if eq $child_key "children"}} + {{- $newCtx := addToChild $child_value "Indent" " " -}} + {{- template "nestedChildrenRemoveOne" $newCtx }} + {{- else if ne $child_key "deletable_child"}} + {{$child_key}} = "{{$child_value}}" + {{- end}} {{- end}} }, - {{- end}} + {{- end}} + {{- end}} ] {{- end}} } @@ -784,8 +803,23 @@ resource "aci_{{$.resourceName}}" "test" { {{$key}} = "{{$value}}" {{- end}} {{- range $key, $value := $.children}} - {{$key}} = [] - {{- end}} + {{$key}} = [ + {{- range $index, $child := $value}} + {{- if not $child.deletable_child }} + { + {{- range $child_key, $child_value := $child}} + {{- if eq $child_key "children"}} + {{- $newCtx := addToChild $child_value "Indent" " " -}} + {{- template "nestedChildrenRemoveAll" $newCtx }} + {{- else if ne $child_key "deletable_child"}} + {{$child_key}} = "{{$child_value}}" + {{- end}} + {{- end}} + }, + {{- end}} + {{- end}} + ] + {{- end}} } ` @@ -812,4 +846,50 @@ resource "aci_{{$.resourceName}}" "test" { {{- end}} {{$indent}}] {{- end}} +{{- end}} + +{{/* A sub template for including nested children by removing only one child that is deletable. */}} +{{- define "nestedChildrenRemoveOne" -}} + {{- $indent := .TemplateProperties.Indent -}} + {{- range $key, $value := .childValue}} + {{$indent}}{{$key}} = [ + {{- range $index, $child := $value}} + {{- if or (ne $index 0) (and (eq $index 0) (not $child.deletable_child)) }} + {{$indent}}{ + {{- range $child_key, $child_value := $child}} + {{- if eq $child_key "children"}} + {{- $newCtx := addToChild $child_value "Indent" (print $indent " ") -}} + {{- template "nestedChildrenRemoveOne" $newCtx }} + {{- else if ne $child_key "deletable_child"}} + {{$indent}}{{$child_key}} = "{{$child_value}}" + {{- end}} + {{- end}} + {{$indent}}}, + {{- end}} + {{- end}} + {{$indent}}] +{{- end}} +{{- end}} + +{{/* A sub template for including nested children by removing all deletable children. */}} +{{- define "nestedChildrenRemoveAll" -}} + {{- $indent := .TemplateProperties.Indent -}} + {{- range $key, $value := .childValue}} + {{$indent}}{{$key}} = [ + {{- range $index, $child := $value}} + {{- if not $child.deletable_child }} + {{$indent}}{ + {{- range $child_key, $child_value := $child}} + {{- if eq $child_key "children"}} + {{- $newCtx := addToChild $child_value "Indent" (print $indent " ") -}} + {{- template "nestedChildrenRemoveAll" $newCtx }} + {{- else if ne $child_key "deletable_child"}} + {{$indent}}{{$child_key}} = "{{$child_value}}" + {{- end}} + {{- end}} + {{$indent}}}, + {{- end}} + {{- end}} + {{$indent}}] +{{- end}} {{- end}} \ No newline at end of file diff --git a/gen/templates/testvars.yaml.tmpl b/gen/templates/testvars.yaml.tmpl index 95ae78494..dd10ff2cd 100644 --- a/gen/templates/testvars.yaml.tmpl +++ b/gen/templates/testvars.yaml.tmpl @@ -113,9 +113,20 @@ targets: {{- $enteredPropertiesZone1 := false }} {{ $indent }}- {{ range .Properties}}{{- if $enteredPropertiesZone1 }}{{ $indent }}{{- else}}{{- $enteredPropertiesZone1 = true }}{{- end}}{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}: {{$length := len .ValidValues}}{{if ne $length 0}}"{{ index .ValidValues 0 }}"{{else if not .IsNaming}}"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}_1"{{- else}}"{{lookupChildTestValue .PkgName $.ResourceName .SnakeCaseName $.TestVars 0 $.Definitions}}"{{- end}} {{ end}} + {{- if $child_deletable -}} + {{ $indent }}deletable_child: true + {{- else -}} + {{ $indent }}deletable_child: false + {{ end}} {{- $enteredPropertiesZone2 := false }} {{ $indent }}- {{ range .Properties}}{{- if $enteredPropertiesZone2 }}{{ $indent }}{{- else}}{{- $enteredPropertiesZone2 = true }}{{- end}}{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}: {{$length := len .ValidValues}}{{if ge $length 2}}"{{ index .ValidValues 1 }}"{{else if not .IsNaming}}"{{overwriteProperty .PkgName .SnakeCaseName $.Definitions}}_2"{{- else}}"{{lookupChildTestValue .PkgName $.ResourceName .SnakeCaseName $.TestVars 1 $.Definitions}}"{{- end}} - {{ end}}{{- end}} + {{ end}} + {{- if $child_deletable -}} + {{ $indent }}deletable_child: true + {{- else -}} + {{ $indent }}deletable_child: false + {{ end}} + {{- end}} {{- $enteredGrandChildZone := false }} {{- range .Children}} {{- if not $enteredGrandChildZone }} diff --git a/gen/testvars/commPol.yaml b/gen/testvars/commPol.yaml index e2ef9c941..f4d5678b6 100644 --- a/gen/testvars/commPol.yaml +++ b/gen/testvars/commPol.yaml @@ -62,17 +62,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true key_ring: - annotation: "annotation_1" tn_pki_key_ring_name: "tn_pki_key_ring_name_1" @@ -82,45 +82,45 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true diff --git a/gen/testvars/fvEpIpTag.yaml b/gen/testvars/fvEpIpTag.yaml index ddf3a5b44..095a2670c 100644 --- a/gen/testvars/fvEpIpTag.yaml +++ b/gen/testvars/fvEpIpTag.yaml @@ -30,17 +30,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "fvTenant" parent_dependency: "" diff --git a/gen/testvars/fvEpMacTag.yaml b/gen/testvars/fvEpMacTag.yaml index d86a849d4..0cbf94c56 100644 --- a/gen/testvars/fvEpMacTag.yaml +++ b/gen/testvars/fvEpMacTag.yaml @@ -30,17 +30,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "fvTenant" parent_dependency: "" diff --git a/gen/testvars/fvFBRGroup.yaml b/gen/testvars/fvFBRGroup.yaml index d76ad44a4..4014b0043 100644 --- a/gen/testvars/fvFBRGroup.yaml +++ b/gen/testvars/fvFBRGroup.yaml @@ -28,42 +28,42 @@ children: name: "name_1" name_alias: "name_alias_1" fallback_member: "2.2.2.2" - + deletable_child: true - annotation: "annotation_2" description: "description_2" name: "name_2" name_alias: "name_alias_2" fallback_member: "2.2.2.3" - + deletable_child: true children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "fvCtx" parent_dependency: "fvTenant" diff --git a/gen/testvars/fvFBRMember.yaml b/gen/testvars/fvFBRMember.yaml index 2e5ab882f..74b03e842 100644 --- a/gen/testvars/fvFBRMember.yaml +++ b/gen/testvars/fvFBRMember.yaml @@ -27,17 +27,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "fvFBRGroup" parent_dependency: "fvCtx" diff --git a/gen/testvars/l3extConsLbl.yaml b/gen/testvars/l3extConsLbl.yaml index fa89a9f82..fbc2dbb2c 100644 --- a/gen/testvars/l3extConsLbl.yaml +++ b/gen/testvars/l3extConsLbl.yaml @@ -33,17 +33,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "l3extOut" parent_dependency: "" diff --git a/gen/testvars/l3extProvLbl.yaml b/gen/testvars/l3extProvLbl.yaml index cf5d6be02..a1d05a147 100644 --- a/gen/testvars/l3extProvLbl.yaml +++ b/gen/testvars/l3extProvLbl.yaml @@ -31,17 +31,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "l3extOut" parent_dependency: "fvTenant" diff --git a/gen/testvars/l3extRsOutToFBRGroup.yaml b/gen/testvars/l3extRsOutToFBRGroup.yaml index 4aa03a0ed..1c4e1f32d 100644 --- a/gen/testvars/l3extRsOutToFBRGroup.yaml +++ b/gen/testvars/l3extRsOutToFBRGroup.yaml @@ -21,17 +21,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "l3extOut" parent_dependency: "fvTenant" diff --git a/gen/testvars/l3extRsRedistributePol.yaml b/gen/testvars/l3extRsRedistributePol.yaml index 775eb2974..b0938f28b 100644 --- a/gen/testvars/l3extRsRedistributePol.yaml +++ b/gen/testvars/l3extRsRedistributePol.yaml @@ -26,17 +26,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "l3extOut" parent_dependency: "fvTenant" diff --git a/gen/testvars/mgmtInstP.yaml b/gen/testvars/mgmtInstP.yaml index 559715152..e0766074e 100644 --- a/gen/testvars/mgmtInstP.yaml +++ b/gen/testvars/mgmtInstP.yaml @@ -28,40 +28,40 @@ children: - annotation: "annotation_1" priority: "level1" out_of_band_contract_name: "out_of_band_contract_name_0" - + deletable_child: true - annotation: "annotation_2" priority: "level2" out_of_band_contract_name: "out_of_band_contract_name_1" - + deletable_child: true children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true diff --git a/gen/testvars/mgmtRsOoBCons.yaml b/gen/testvars/mgmtRsOoBCons.yaml index cc689e5c0..44ef3bca5 100644 --- a/gen/testvars/mgmtRsOoBCons.yaml +++ b/gen/testvars/mgmtRsOoBCons.yaml @@ -23,17 +23,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "mgmtInstP" parent_dependency: "" diff --git a/gen/testvars/mgmtSubnet.yaml b/gen/testvars/mgmtSubnet.yaml index 034b37134..7fa94d6d8 100644 --- a/gen/testvars/mgmtSubnet.yaml +++ b/gen/testvars/mgmtSubnet.yaml @@ -27,17 +27,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "mgmtInstP" parent_dependency: "" diff --git a/gen/testvars/mplsNodeSidP.yaml b/gen/testvars/mplsNodeSidP.yaml index 7c5473c56..7e033a56c 100644 --- a/gen/testvars/mplsNodeSidP.yaml +++ b/gen/testvars/mplsNodeSidP.yaml @@ -29,17 +29,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "l3extLoopBackIfP" parent_dependency: "l3extRsNodeL3OutAtt" diff --git a/gen/testvars/netflowMonitorPol.yaml b/gen/testvars/netflowMonitorPol.yaml index 37f9e3a02..dac799c08 100644 --- a/gen/testvars/netflowMonitorPol.yaml +++ b/gen/testvars/netflowMonitorPol.yaml @@ -29,25 +29,25 @@ children: relation_to_netflow_exporters: - annotation: "annotation_1" netflow_exporter_policy_name: "netflow_exporter_policy_name_0" - + deletable_child: true - annotation: "annotation_2" netflow_exporter_policy_name: "netflow_exporter_policy_name_1" - + deletable_child: true children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true relation_to_netflow_record: - annotation: "annotation_1" netflow_record_policy_name: "netflow_record_policy_name_1" @@ -57,31 +57,31 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "fvTenant" parent_dependency: "" diff --git a/gen/testvars/netflowRsMonitorToExporter.yaml b/gen/testvars/netflowRsMonitorToExporter.yaml index d429e297f..900f1a246 100644 --- a/gen/testvars/netflowRsMonitorToExporter.yaml +++ b/gen/testvars/netflowRsMonitorToExporter.yaml @@ -21,17 +21,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "netflowMonitorPol" parent_dependency: "fvTenant" diff --git a/gen/testvars/pimRouteMapEntry.yaml b/gen/testvars/pimRouteMapEntry.yaml index 4b4d055d9..0a6122f7e 100644 --- a/gen/testvars/pimRouteMapEntry.yaml +++ b/gen/testvars/pimRouteMapEntry.yaml @@ -35,17 +35,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "pimRouteMapPol" parent_dependency: "fvTenant" diff --git a/gen/testvars/pimRouteMapPol.yaml b/gen/testvars/pimRouteMapPol.yaml index 560c67e84..78b362ce0 100644 --- a/gen/testvars/pimRouteMapPol.yaml +++ b/gen/testvars/pimRouteMapPol.yaml @@ -29,17 +29,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true parents: - class_name: "fvTenant" parent_dependency: "" diff --git a/gen/testvars/vzOOBBrCP.yaml b/gen/testvars/vzOOBBrCP.yaml index 4c6d23c3f..16820b042 100644 --- a/gen/testvars/vzOOBBrCP.yaml +++ b/gen/testvars/vzOOBBrCP.yaml @@ -37,17 +37,17 @@ children: annotations: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true tags: - key: "key_0" value: "value_1" - + deletable_child: true - key: "key_1" value: "value_2" - + deletable_child: true diff --git a/internal/provider/resource_aci_communication_policy_test.go b/internal/provider/resource_aci_communication_policy_test.go index 6d49e19e6..db3752da7 100644 --- a/internal/provider/resource_aci_communication_policy_test.go +++ b/internal/provider/resource_aci_communication_policy_test.go @@ -102,7 +102,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] key_ring:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:false tn_pki_key_ring_name:tn_pki_key_ring_name_1]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tp:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:true target_dn:target_dn_1]]]"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] key_ring:[map[annotation:annotation_1 children:map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]] deletable_child:false tn_pki_key_ring_name:tn_pki_key_ring_name_1]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tp:[map[annotation:annotation_1 children:map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]] deletable_child:true target_dn:target_dn_1]]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), @@ -148,7 +148,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] key_ring:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:false tn_pki_key_ring_name:tn_pki_key_ring_name_1]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tp:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:true target_dn:target_dn_1]]]"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] key_ring:[map[annotation:annotation_1 children:map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]] deletable_child:false tn_pki_key_ring_name:tn_pki_key_ring_name_1]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tp:[map[annotation:annotation_1 children:map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]] deletable_child:true target_dn:target_dn_1]]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), @@ -185,6 +185,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_key", ""), resource.TestCheckResourceAttr("aci_communication_policy.test", "owner_tag", ""), resource.TestCheckResourceAttr("aci_communication_policy.test", "strict_security_on_apic_oob_subnet", "false"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_communication_policy.test", "annotations.#", "1"), @@ -192,7 +193,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] key_ring:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:false tn_pki_key_ring_name:tn_pki_key_ring_name_1]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tp:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:true target_dn:target_dn_1]]]"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] key_ring:[map[annotation:annotation_1 children:map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]] deletable_child:false tn_pki_key_ring_name:tn_pki_key_ring_name_1]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tp:[map[annotation:annotation_1 children:map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]] deletable_child:true target_dn:target_dn_1]]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), @@ -212,6 +213,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.throttle_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.visore_access", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.#", "1"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_communication_policy.test", "tags.#", "1"), @@ -232,7 +234,7 @@ func TestAccResourceCommPol(t *testing.T) { resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.access_control_allow_origins", "access_control_allow_origins_1"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.admin_st", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] key_ring:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:false tn_pki_key_ring_name:tn_pki_key_ring_name_1]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tp:[map[annotation:annotation_1 children:map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]] deletable_child:true target_dn:target_dn_1]]]"), + resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] key_ring:[map[annotation:annotation_1 children:map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]] deletable_child:false tn_pki_key_ring_name:tn_pki_key_ring_name_1]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tp:[map[annotation:annotation_1 children:map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]] deletable_child:true target_dn:target_dn_1]]]"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.cli_only_mode", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.client_cert_auth_state", "disabled"), resource.TestCheckResourceAttr("aci_communication_policy.test", "http_ssl_configuration.0.description", "description_1"), @@ -422,19 +424,73 @@ const testConfigCommPolChildrenRemoveOne = ` resource "aci_communication_policy" "test" { name = "test_name" annotations = [ - { - key = "key_1" - value = "value_2" + key = "key_1" + value = "value_2" }, ] http_ssl_configuration = [ + { + access_control_allow_credential = "disabled" + access_control_allow_origins = "access_control_allow_origins_1" + admin_st = "disabled" + annotation = "annotation_1" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + key_ring = [ + { + annotation = "annotation_1" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] + tn_pki_key_ring_name = "tn_pki_key_ring_name_1" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] + tp = [ + ] + cli_only_mode = "disabled" + client_cert_auth_state = "disabled" + description = "description_1" + dh_param = "1024" + global_throttle_rate = "global_throttle_rate_1" + global_throttle_st = "disabled" + global_throttle_unit = "global_throttle_unit_1" + max_request_status_count = "max_request_status_count_1" + name = "name_1" + name_alias = "name_alias_1" + node_exporter = "disabled" + port = "port_1" + referer = "referer_1" + server_header = "disabled" + ssl_protocols = "TLSv1" + throttle_rate = "throttle_rate_1" + throttle_st = "disabled" + visore_access = "disabled" + }, ] tags = [ - { - key = "key_1" - value = "value_2" + key = "key_1" + value = "value_2" }, ] } @@ -443,8 +499,51 @@ resource "aci_communication_policy" "test" { const testConfigCommPolChildrenRemoveAll = ` resource "aci_communication_policy" "test" { name = "test_name" - annotations = [] - http_ssl_configuration = [] - tags = [] + annotations = [ + ] + http_ssl_configuration = [ + { + access_control_allow_credential = "disabled" + access_control_allow_origins = "access_control_allow_origins_1" + admin_st = "disabled" + annotation = "annotation_1" + annotations = [ + ] + key_ring = [ + { + annotation = "annotation_1" + annotations = [ + ] + tags = [ + ] + tn_pki_key_ring_name = "tn_pki_key_ring_name_1" + }, + ] + tags = [ + ] + tp = [ + ] + cli_only_mode = "disabled" + client_cert_auth_state = "disabled" + description = "description_1" + dh_param = "1024" + global_throttle_rate = "global_throttle_rate_1" + global_throttle_st = "disabled" + global_throttle_unit = "global_throttle_unit_1" + max_request_status_count = "max_request_status_count_1" + name = "name_1" + name_alias = "name_alias_1" + node_exporter = "disabled" + port = "port_1" + referer = "referer_1" + server_header = "disabled" + ssl_protocols = "TLSv1" + throttle_rate = "throttle_rate_1" + throttle_st = "disabled" + visore_access = "disabled" + }, + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_endpoint_tag_ip_test.go b/internal/provider/resource_aci_endpoint_tag_ip_test.go index ca8f2a19f..433ddc625 100644 --- a/internal/provider/resource_aci_endpoint_tag_ip_test.go +++ b/internal/provider/resource_aci_endpoint_tag_ip_test.go @@ -143,9 +143,11 @@ func TestAccResourceFvEpIpTagWithFvTenant(t *testing.T) { Config: testConfigFvEpIpTagChildrenRemoveOneDependencyWithFvTenant, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_endpoint_tag_ip.test", "tags.#", "1"), @@ -236,17 +238,17 @@ resource "aci_endpoint_tag_ip" "test" { parent_dn = aci_tenant.test.id ip = "10.0.0.2" vrf_name = "test_ctx_name" - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - tags = [ - { + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] } ` @@ -256,7 +258,9 @@ resource "aci_endpoint_tag_ip" "test" { parent_dn = aci_tenant.test.id ip = "10.0.0.2" vrf_name = "test_ctx_name" - annotations = [] - tags = [] + annotations = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_endpoint_tag_mac_test.go b/internal/provider/resource_aci_endpoint_tag_mac_test.go index 5dd5781ef..c8d3bb6a3 100644 --- a/internal/provider/resource_aci_endpoint_tag_mac_test.go +++ b/internal/provider/resource_aci_endpoint_tag_mac_test.go @@ -143,9 +143,11 @@ func TestAccResourceFvEpMacTagWithFvTenant(t *testing.T) { Config: testConfigFvEpMacTagChildrenRemoveOneDependencyWithFvTenant, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_endpoint_tag_mac.test", "tags.#", "1"), @@ -236,17 +238,17 @@ resource "aci_endpoint_tag_mac" "test" { parent_dn = aci_tenant.test.id bd_name = "test_bd_name" mac = "00:00:00:00:00:01" - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - tags = [ - { + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] } ` @@ -256,7 +258,9 @@ resource "aci_endpoint_tag_mac" "test" { parent_dn = aci_tenant.test.id bd_name = "test_bd_name" mac = "00:00:00:00:00:01" - annotations = [] - tags = [] + annotations = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_external_management_network_instance_profile_test.go b/internal/provider/resource_aci_external_management_network_instance_profile_test.go index 521e16644..7eaaa5115 100644 --- a/internal/provider/resource_aci_external_management_network_instance_profile_test.go +++ b/internal/provider/resource_aci_external_management_network_instance_profile_test.go @@ -90,7 +90,7 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.priority", "level2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "2"), @@ -118,7 +118,7 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_0"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.1.priority", "level2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "2"), @@ -137,14 +137,17 @@ func TestAccResourceMgmtInstP(t *testing.T) { resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "description", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "name_alias", ""), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "priority", "unspecified"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "annotations.#", "1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.out_of_band_contract_name", "out_of_band_contract_name_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.0.priority", "level2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "relation_to_consumed_out_of_band_contracts.#", "1"), + resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_external_management_network_instance_profile.test", "tags.#", "1"), @@ -260,26 +263,34 @@ const testConfigMgmtInstPChildrenRemoveOne = ` resource "aci_external_management_network_instance_profile" "test" { name = "test_name" annotations = [ - { - key = "key_1" - value = "value_2" + key = "key_1" + value = "value_2" }, ] relation_to_consumed_out_of_band_contracts = [ - { - annotation = "annotation_2" - children = "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]" - out_of_band_contract_name = "out_of_band_contract_name_1" - priority = "level2" + annotation = "annotation_2" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] + out_of_band_contract_name = "out_of_band_contract_name_1" + priority = "level2" }, ] tags = [ - { - key = "key_1" - value = "value_2" + key = "key_1" + value = "value_2" }, ] } @@ -288,8 +299,11 @@ resource "aci_external_management_network_instance_profile" "test" { const testConfigMgmtInstPChildrenRemoveAll = ` resource "aci_external_management_network_instance_profile" "test" { name = "test_name" - annotations = [] - relation_to_consumed_out_of_band_contracts = [] - tags = [] + annotations = [ + ] + relation_to_consumed_out_of_band_contracts = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_external_management_network_subnet_test.go b/internal/provider/resource_aci_external_management_network_subnet_test.go index 6bdd85a8f..cc0167271 100644 --- a/internal/provider/resource_aci_external_management_network_subnet_test.go +++ b/internal/provider/resource_aci_external_management_network_subnet_test.go @@ -136,9 +136,11 @@ func TestAccResourceMgmtSubnetWithMgmtInstP(t *testing.T) { Config: testConfigMgmtSubnetChildrenRemoveOneDependencyWithMgmtInstP, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_external_management_network_subnet.test", "tags.#", "1"), @@ -223,17 +225,17 @@ const testConfigMgmtSubnetChildrenRemoveOneDependencyWithMgmtInstP = testConfigM resource "aci_external_management_network_subnet" "test" { parent_dn = aci_external_management_network_instance_profile.test.id ip = "1.1.1.0/24" - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - tags = [ - { + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] } ` @@ -242,7 +244,9 @@ const testConfigMgmtSubnetChildrenRemoveAllDependencyWithMgmtInstP = testConfigM resource "aci_external_management_network_subnet" "test" { parent_dn = aci_external_management_network_instance_profile.test.id ip = "1.1.1.0/24" - annotations = [] - tags = [] + annotations = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_l3out_consumer_label_test.go b/internal/provider/resource_aci_l3out_consumer_label_test.go index 01a8459da..97e1962cc 100644 --- a/internal/provider/resource_aci_l3out_consumer_label_test.go +++ b/internal/provider/resource_aci_l3out_consumer_label_test.go @@ -154,9 +154,11 @@ func TestAccResourceL3extConsLblWithL3extOut(t *testing.T) { Config: testConfigL3extConsLblChildrenRemoveOneDependencyWithL3extOut, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_l3out_consumer_label.test", "tags.#", "1"), @@ -247,17 +249,17 @@ const testConfigL3extConsLblChildrenRemoveOneDependencyWithL3extOut = testConfig resource "aci_l3out_consumer_label" "test" { parent_dn = aci_l3_outside.test.id name = "test_name" - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - tags = [ - { + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] } ` @@ -266,7 +268,9 @@ const testConfigL3extConsLblChildrenRemoveAllDependencyWithL3extOut = testConfig resource "aci_l3out_consumer_label" "test" { parent_dn = aci_l3_outside.test.id name = "test_name" - annotations = [] - tags = [] + annotations = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_l3out_node_sid_profile_test.go b/internal/provider/resource_aci_l3out_node_sid_profile_test.go index 553f66076..c479d6712 100644 --- a/internal/provider/resource_aci_l3out_node_sid_profile_test.go +++ b/internal/provider/resource_aci_l3out_node_sid_profile_test.go @@ -142,9 +142,11 @@ func TestAccResourceMplsNodeSidPWithL3extLoopBackIfP(t *testing.T) { Config: testConfigMplsNodeSidPChildrenRemoveOneDependencyWithL3extLoopBackIfP, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_l3out_node_sid_profile.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_l3out_node_sid_profile.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_l3out_node_sid_profile.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_l3out_node_sid_profile.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_l3out_node_sid_profile.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_l3out_node_sid_profile.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_l3out_node_sid_profile.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_l3out_node_sid_profile.test", "tags.#", "1"), @@ -231,17 +233,17 @@ const testConfigMplsNodeSidPChildrenRemoveOneDependencyWithL3extLoopBackIfP = te resource "aci_l3out_node_sid_profile" "test" { parent_dn = aci_l3out_loopback_interface_profile.test.id segment_id = "1" - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - tags = [ - { + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] } ` @@ -250,7 +252,9 @@ const testConfigMplsNodeSidPChildrenRemoveAllDependencyWithL3extLoopBackIfP = te resource "aci_l3out_node_sid_profile" "test" { parent_dn = aci_l3out_loopback_interface_profile.test.id segment_id = "1" - annotations = [] - tags = [] + annotations = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_l3out_provider_label_test.go b/internal/provider/resource_aci_l3out_provider_label_test.go index 62a576782..bf14e99ea 100644 --- a/internal/provider/resource_aci_l3out_provider_label_test.go +++ b/internal/provider/resource_aci_l3out_provider_label_test.go @@ -148,9 +148,11 @@ func TestAccResourceL3extProvLblWithL3extOut(t *testing.T) { Config: testConfigL3extProvLblChildrenRemoveOneDependencyWithL3extOut, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_l3out_provider_label.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_l3out_provider_label.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_l3out_provider_label.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_l3out_provider_label.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_l3out_provider_label.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_l3out_provider_label.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_l3out_provider_label.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_l3out_provider_label.test", "tags.#", "1"), @@ -239,17 +241,17 @@ const testConfigL3extProvLblChildrenRemoveOneDependencyWithL3extOut = testConfig resource "aci_l3out_provider_label" "test" { parent_dn = aci_l3_outside.test.id name = "prov_label" - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - tags = [ - { + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] } ` @@ -258,7 +260,9 @@ const testConfigL3extProvLblChildrenRemoveAllDependencyWithL3extOut = testConfig resource "aci_l3out_provider_label" "test" { parent_dn = aci_l3_outside.test.id name = "prov_label" - annotations = [] - tags = [] + annotations = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_l3out_redistribute_policy_test.go b/internal/provider/resource_aci_l3out_redistribute_policy_test.go index dae8b08af..b2dd12b85 100644 --- a/internal/provider/resource_aci_l3out_redistribute_policy_test.go +++ b/internal/provider/resource_aci_l3out_redistribute_policy_test.go @@ -125,9 +125,11 @@ func TestAccResourceL3extRsRedistributePolWithL3extOut(t *testing.T) { Config: testConfigL3extRsRedistributePolChildrenRemoveOneDependencyWithL3extOut, ExpectNonEmptyPlan: true, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_l3out_redistribute_policy.test", "tags.#", "1"), @@ -212,17 +214,17 @@ resource "aci_l3out_redistribute_policy" "test" { parent_dn = aci_l3_outside.test.id route_control_profile_name = "test_tn_rtctrl_profile_name" source = "direct" - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - tags = [ - { + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] } ` @@ -232,7 +234,9 @@ resource "aci_l3out_redistribute_policy" "test" { parent_dn = aci_l3_outside.test.id route_control_profile_name = "test_tn_rtctrl_profile_name" source = "direct" - annotations = [] - tags = [] + annotations = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_netflow_monitor_policy_test.go b/internal/provider/resource_aci_netflow_monitor_policy_test.go index 586f5f195..c055b9fd1 100644 --- a/internal/provider/resource_aci_netflow_monitor_policy_test.go +++ b/internal/provider/resource_aci_netflow_monitor_policy_test.go @@ -95,10 +95,10 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.netflow_exporter_policy_name", "netflow_exporter_policy_name_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.netflow_exporter_policy_name", "netflow_exporter_policy_name_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.value", "value_1"), @@ -125,10 +125,10 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.netflow_exporter_policy_name", "netflow_exporter_policy_name_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.netflow_exporter_policy_name", "netflow_exporter_policy_name_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.key", "key_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.value", "value_1"), @@ -149,11 +149,11 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.annotation", "annotation_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.netflow_exporter_policy_name", "netflow_exporter_policy_name_0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.1.netflow_exporter_policy_name", "netflow_exporter_policy_name_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.#", "2"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.#", "1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.key", "key_0"), @@ -168,17 +168,20 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { Config: testConfigNetflowMonitorPolChildrenRemoveOneDependencyWithFvTenant, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "annotations.#", "1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.0.netflow_exporter_policy_name", "netflow_exporter_policy_name_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.#", "1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.#", "1"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.#", "1"), @@ -192,7 +195,7 @@ func TestAccResourceNetflowMonitorPolWithFvTenant(t *testing.T) { resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "annotations.#", "0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_exporters.#", "0"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.annotation", "annotation_1"), - resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.0.netflow_record_policy_name", "netflow_record_policy_name_1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "relation_to_netflow_record.#", "1"), resource.TestCheckResourceAttr("aci_netflow_monitor_policy.test", "tags.#", "0"), @@ -253,14 +256,52 @@ resource "aci_netflow_monitor_policy" "test" { }, { annotation = "annotation_2" - children = "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] netflow_exporter_policy_name = "netflow_exporter_policy_name_1" }, ] relation_to_netflow_record = [ { annotation = "annotation_1" - children = "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] netflow_record_policy_name = "netflow_record_policy_name_1" }, ] @@ -288,24 +329,53 @@ const testConfigNetflowMonitorPolChildrenRemoveOneDependencyWithFvTenant = testC resource "aci_netflow_monitor_policy" "test" { parent_dn = aci_tenant.test.id name = "netfow_monitor" - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - relation_to_netflow_exporters = [ - { + relation_to_netflow_exporters = [ + { annotation = "annotation_2" - children = "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] netflow_exporter_policy_name = "netflow_exporter_policy_name_1" - }, + }, ] - tags = [ - { + relation_to_netflow_record = [ + { + annotation = "annotation_1" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] + netflow_record_policy_name = "netflow_record_policy_name_1" + }, + ] + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] } ` @@ -314,8 +384,21 @@ const testConfigNetflowMonitorPolChildrenRemoveAllDependencyWithFvTenant = testC resource "aci_netflow_monitor_policy" "test" { parent_dn = aci_tenant.test.id name = "netfow_monitor" - annotations = [] - relation_to_netflow_exporters = [] - tags = [] + annotations = [ + ] + relation_to_netflow_exporters = [ + ] + relation_to_netflow_record = [ + { + annotation = "annotation_1" + annotations = [ + ] + tags = [ + ] + netflow_record_policy_name = "netflow_record_policy_name_1" + }, + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_out_of_band_contract_test.go b/internal/provider/resource_aci_out_of_band_contract_test.go index 45ff9312e..cf25dd6f1 100644 --- a/internal/provider/resource_aci_out_of_band_contract_test.go +++ b/internal/provider/resource_aci_out_of_band_contract_test.go @@ -161,9 +161,11 @@ func TestAccResourceVzOOBBrCP(t *testing.T) { resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "priority", "unspecified"), resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "scope", "context"), resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "target_dscp", "unspecified"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_out_of_band_contract.test", "tags.#", "1"), @@ -261,17 +263,15 @@ const testConfigVzOOBBrCPChildrenRemoveOne = ` resource "aci_out_of_band_contract" "test" { name = "test_name" annotations = [ - { - key = "key_1" - value = "value_2" + key = "key_1" + value = "value_2" }, ] tags = [ - { - key = "key_1" - value = "value_2" + key = "key_1" + value = "value_2" }, ] } @@ -280,7 +280,9 @@ resource "aci_out_of_band_contract" "test" { const testConfigVzOOBBrCPChildrenRemoveAll = ` resource "aci_out_of_band_contract" "test" { name = "test_name" - annotations = [] - tags = [] + annotations = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_pim_route_map_entry_test.go b/internal/provider/resource_aci_pim_route_map_entry_test.go index 162dade9a..0fe836ccb 100644 --- a/internal/provider/resource_aci_pim_route_map_entry_test.go +++ b/internal/provider/resource_aci_pim_route_map_entry_test.go @@ -160,9 +160,11 @@ func TestAccResourcePimRouteMapEntryWithPimRouteMapPol(t *testing.T) { Config: testConfigPimRouteMapEntryChildrenRemoveOneDependencyWithPimRouteMapPol, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_pim_route_map_entry.test", "tags.#", "1"), @@ -255,17 +257,17 @@ const testConfigPimRouteMapEntryChildrenRemoveOneDependencyWithPimRouteMapPol = resource "aci_pim_route_map_entry" "test" { parent_dn = aci_pim_route_map_policy.test.id order = "1" - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - tags = [ - { + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] } ` @@ -274,7 +276,9 @@ const testConfigPimRouteMapEntryChildrenRemoveAllDependencyWithPimRouteMapPol = resource "aci_pim_route_map_entry" "test" { parent_dn = aci_pim_route_map_policy.test.id order = "1" - annotations = [] - tags = [] + annotations = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_pim_route_map_policy_test.go b/internal/provider/resource_aci_pim_route_map_policy_test.go index aff79ff65..f20c802d1 100644 --- a/internal/provider/resource_aci_pim_route_map_policy_test.go +++ b/internal/provider/resource_aci_pim_route_map_policy_test.go @@ -142,9 +142,11 @@ func TestAccResourcePimRouteMapPolWithFvTenant(t *testing.T) { Config: testConfigPimRouteMapPolChildrenRemoveOneDependencyWithFvTenant, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_pim_route_map_policy.test", "tags.#", "1"), @@ -231,17 +233,17 @@ const testConfigPimRouteMapPolChildrenRemoveOneDependencyWithFvTenant = testConf resource "aci_pim_route_map_policy" "test" { parent_dn = aci_tenant.test.id name = "test_name" - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - tags = [ - { + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] } ` @@ -250,7 +252,9 @@ const testConfigPimRouteMapPolChildrenRemoveAllDependencyWithFvTenant = testConf resource "aci_pim_route_map_policy" "test" { parent_dn = aci_tenant.test.id name = "test_name" - annotations = [] - tags = [] + annotations = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract_test.go b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract_test.go index 14bf7e258..10e870da1 100644 --- a/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract_test.go +++ b/internal/provider/resource_aci_relation_to_consumed_out_of_band_contract_test.go @@ -124,9 +124,11 @@ func TestAccResourceMgmtRsOoBConsWithMgmtInstP(t *testing.T) { Config: testConfigMgmtRsOoBConsChildrenRemoveOneDependencyWithMgmtInstP, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_relation_to_consumed_out_of_band_contract.test", "tags.#", "1"), @@ -207,17 +209,17 @@ const testConfigMgmtRsOoBConsChildrenRemoveOneDependencyWithMgmtInstP = testConf resource "aci_relation_to_consumed_out_of_band_contract" "test" { parent_dn = aci_external_management_network_instance_profile.test.id out_of_band_contract_name = "test_tn_vz_oob_br_cp_name" - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - tags = [ - { + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] } ` @@ -226,7 +228,9 @@ const testConfigMgmtRsOoBConsChildrenRemoveAllDependencyWithMgmtInstP = testConf resource "aci_relation_to_consumed_out_of_band_contract" "test" { parent_dn = aci_external_management_network_instance_profile.test.id out_of_band_contract_name = "test_tn_vz_oob_br_cp_name" - annotations = [] - tags = [] + annotations = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_relation_to_fallback_route_group_test.go b/internal/provider/resource_aci_relation_to_fallback_route_group_test.go index 6d59993bf..ce7241e82 100644 --- a/internal/provider/resource_aci_relation_to_fallback_route_group_test.go +++ b/internal/provider/resource_aci_relation_to_fallback_route_group_test.go @@ -118,9 +118,11 @@ func TestAccResourceL3extRsOutToFBRGroupWithL3extOut(t *testing.T) { Config: testConfigL3extRsOutToFBRGroupChildrenRemoveOneDependencyWithL3extOut, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_relation_to_fallback_route_group.test", "tags.#", "1"), @@ -206,17 +208,17 @@ const testConfigL3extRsOutToFBRGroupChildrenRemoveOneDependencyWithL3extOut = te resource "aci_relation_to_fallback_route_group" "test" { parent_dn = aci_l3_outside.test.id target_dn = aci_vrf_fallback_route_group.test.id - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - tags = [ - { + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] } ` @@ -225,7 +227,9 @@ const testConfigL3extRsOutToFBRGroupChildrenRemoveAllDependencyWithL3extOut = te resource "aci_relation_to_fallback_route_group" "test" { parent_dn = aci_l3_outside.test.id target_dn = aci_vrf_fallback_route_group.test.id - annotations = [] - tags = [] + annotations = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_relation_to_netflow_exporter_test.go b/internal/provider/resource_aci_relation_to_netflow_exporter_test.go index d913e16f1..ef070a87d 100644 --- a/internal/provider/resource_aci_relation_to_netflow_exporter_test.go +++ b/internal/provider/resource_aci_relation_to_netflow_exporter_test.go @@ -118,9 +118,11 @@ func TestAccResourceNetflowRsMonitorToExporterWithNetflowMonitorPol(t *testing.T Config: testConfigNetflowRsMonitorToExporterChildrenRemoveOneDependencyWithNetflowMonitorPol, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_relation_to_netflow_exporter.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_relation_to_netflow_exporter.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_relation_to_netflow_exporter.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_relation_to_netflow_exporter.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_relation_to_netflow_exporter.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_relation_to_netflow_exporter.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_relation_to_netflow_exporter.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_relation_to_netflow_exporter.test", "tags.#", "1"), @@ -199,17 +201,17 @@ const testConfigNetflowRsMonitorToExporterChildrenRemoveOneDependencyWithNetflow resource "aci_relation_to_netflow_exporter" "test" { parent_dn = aci_netflow_monitor_policy.test.id netflow_exporter_policy_name = "test_tn_netflow_exporter_pol_name" - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - tags = [ - { + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] } ` @@ -218,7 +220,9 @@ const testConfigNetflowRsMonitorToExporterChildrenRemoveAllDependencyWithNetflow resource "aci_relation_to_netflow_exporter" "test" { parent_dn = aci_netflow_monitor_policy.test.id netflow_exporter_policy_name = "test_tn_netflow_exporter_pol_name" - annotations = [] - tags = [] + annotations = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_vrf_fallback_route_group_member_test.go b/internal/provider/resource_aci_vrf_fallback_route_group_member_test.go index 109e716b9..d9e64d4af 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group_member_test.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group_member_test.go @@ -136,9 +136,11 @@ func TestAccResourceFvFBRMemberWithFvFBRGroup(t *testing.T) { Config: testConfigFvFBRMemberChildrenRemoveOneDependencyWithFvFBRGroup, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group_member.test", "tags.#", "1"), @@ -223,17 +225,17 @@ const testConfigFvFBRMemberChildrenRemoveOneDependencyWithFvFBRGroup = testConfi resource "aci_vrf_fallback_route_group_member" "test" { parent_dn = aci_vrf_fallback_route_group.test.id fallback_member = "2.2.2.3" - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - tags = [ - { + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] } ` @@ -242,7 +244,9 @@ const testConfigFvFBRMemberChildrenRemoveAllDependencyWithFvFBRGroup = testConfi resource "aci_vrf_fallback_route_group_member" "test" { parent_dn = aci_vrf_fallback_route_group.test.id fallback_member = "2.2.2.3" - annotations = [] - tags = [] + annotations = [ + ] + tags = [ + ] } ` diff --git a/internal/provider/resource_aci_vrf_fallback_route_group_test.go b/internal/provider/resource_aci_vrf_fallback_route_group_test.go index aff4e0ed0..a3f024340 100644 --- a/internal/provider/resource_aci_vrf_fallback_route_group_test.go +++ b/internal/provider/resource_aci_vrf_fallback_route_group_test.go @@ -92,7 +92,7 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name", "name_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name_alias", "name_alias_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.description", "description_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.fallback_member", "2.2.2.3"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name", "name_2"), @@ -123,7 +123,7 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name", "name_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name_alias", "name_alias_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.description", "description_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.fallback_member", "2.2.2.3"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name", "name_2"), @@ -151,7 +151,7 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name", "name_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name_alias", "name_alias_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.description", "description_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.fallback_member", "2.2.2.3"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.1.name", "name_2"), @@ -164,14 +164,17 @@ func TestAccResourceFvFBRGroupWithFvCtx(t *testing.T) { Config: testConfigFvFBRGroupChildrenRemoveOneDependencyWithFvCtx, ExpectNonEmptyPlan: false, Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.key", "key_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.0.value", "value_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "annotations.#", "1"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.key", "key_1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.0.value", "value_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "tags.#", "1"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.annotation", "annotation_2"), - resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.children", "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.children", "map[annotations:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]] tags:[map[deletable_child:true key:key_0 value:value_1] map[deletable_child:true key:key_1 value:value_2]]]"), + resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.deletable_child", "true"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.description", "description_2"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.fallback_member", "2.2.2.3"), resource.TestCheckResourceAttr("aci_vrf_fallback_route_group.test", "vrf_fallback_route_group_members.0.name", "name_2"), @@ -253,7 +256,26 @@ resource "aci_vrf_fallback_route_group" "test" { }, { annotation = "annotation_2" - children = "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]" + annotations = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_0" + value = "value_1" + }, + { + key = "key_1" + value = "value_2" + }, + ] description = "description_2" fallback_member = "2.2.2.3" name = "name_2" @@ -274,27 +296,38 @@ const testConfigFvFBRGroupChildrenRemoveOneDependencyWithFvCtx = testConfigFvCtx resource "aci_vrf_fallback_route_group" "test" { parent_dn = aci_vrf.test.id name = "fallback_route_group" - annotations = [ - { + annotations = [ + { key = "key_1" value = "value_2" - }, + }, ] - tags = [ - { + tags = [ + { key = "key_1" value = "value_2" - }, + }, ] - vrf_fallback_route_group_members = [ - { + vrf_fallback_route_group_members = [ + { annotation = "annotation_2" - children = "map[annotations:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]] tags:[map[key:key_0 value:value_1] map[key:key_1 value:value_2]]]" + annotations = [ + { + key = "key_1" + value = "value_2" + }, + ] + tags = [ + { + key = "key_1" + value = "value_2" + }, + ] description = "description_2" fallback_member = "2.2.2.3" name = "name_2" name_alias = "name_alias_2" - }, + }, ] } ` @@ -303,8 +336,11 @@ const testConfigFvFBRGroupChildrenRemoveAllDependencyWithFvCtx = testConfigFvCtx resource "aci_vrf_fallback_route_group" "test" { parent_dn = aci_vrf.test.id name = "fallback_route_group" - annotations = [] - tags = [] - vrf_fallback_route_group_members = [] + annotations = [ + ] + tags = [ + ] + vrf_fallback_route_group_members = [ + ] } ` From 49730551ebfc89f266f70ab6282e8cd4d77fefe3 Mon Sep 17 00:00:00 2001 From: Shreyas Date: Sun, 14 Jul 2024 17:45:16 +0530 Subject: [PATCH 20/20] [ignore] Addition of recursive sub-templates for rendering test check resource attributes for nested children --- gen/templates/resource_test.go.tmpl | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/gen/templates/resource_test.go.tmpl b/gen/templates/resource_test.go.tmpl index b0a05ee5a..4259973be 100644 --- a/gen/templates/resource_test.go.tmpl +++ b/gen/templates/resource_test.go.tmpl @@ -407,7 +407,10 @@ func TestAccResource{{.resourceClassName}}(t *testing.T) { {{- range $key, $value := $.children}} {{- range $child_index, $child := $value}} {{- range $child_key, $child_value := $child}} - {{- if ne $child_key "deletable_child"}} + {{- if eq $child_key "children"}} + {{- $newCtx := addToChild $child_value "ResourceName" (print "aci_" $.resourceName ".test") "InheritedKey" (print $key "." $child_index) -}} + {{- template "testNestedChildren" $newCtx }} + {{- else if ne $child_key "deletable_child"}} resource.TestCheckResourceAttr("aci_{{$.resourceName}}.test", "{{$key}}.{{$child_index}}.{{$child_key}}", "{{$child_value}}"), {{- end}} {{- end}} @@ -827,7 +830,7 @@ resource "aci_{{$.resourceName}}" "test" { {{- end}} -{{/* A sub template for including nested children. */}} +{{/* A sub template for including nested children in the test config. */}} {{- define "nestedChildren" -}} {{- $indent := .TemplateProperties.Indent -}} {{- range $key, $value := .childValue}} @@ -848,7 +851,7 @@ resource "aci_{{$.resourceName}}" "test" { {{- end}} {{- end}} -{{/* A sub template for including nested children by removing only one child that is deletable. */}} +{{/* A sub template for including nested children by removing only one child that is deletable in the test config. */}} {{- define "nestedChildrenRemoveOne" -}} {{- $indent := .TemplateProperties.Indent -}} {{- range $key, $value := .childValue}} @@ -871,7 +874,7 @@ resource "aci_{{$.resourceName}}" "test" { {{- end}} {{- end}} -{{/* A sub template for including nested children by removing all deletable children. */}} +{{/* A sub template for including nested children by removing all deletable children in the test config. */}} {{- define "nestedChildrenRemoveAll" -}} {{- $indent := .TemplateProperties.Indent -}} {{- range $key, $value := .childValue}} @@ -892,4 +895,22 @@ resource "aci_{{$.resourceName}}" "test" { {{- end}} {{$indent}}] {{- end}} +{{- end}} + +{{/* A sub template for testing nested children resource attributes */}} +{{- define "testNestedChildren" -}} + {{- $inheritedKey := .TemplateProperties.InheritedKey -}} + {{- $resourceName := .TemplateProperties.ResourceName -}} + {{- range $key, $value := .childValue}} + {{- range $child_index, $child := $value}} + {{- range $child_key, $child_value := $child}} + {{- if eq $child_key "children"}} + {{- $newCtx := addToChild $child_value "ResourceName" $resourceName "InheritedKey" (print $inheritedKey "." $key "." $child_index) -}} + {{- template "testNestedChildren" $newCtx }} + {{- else if ne $child_key "deletable_child"}} + resource.TestCheckResourceAttr("{{$resourceName}}", "{{$inheritedKey}}.{{$key}}.{{$child_index}}.{{$child_key}}", "{{$child_value}}"), + {{- end}} + {{- end}} + {{- end}} + {{- end}} {{- end}} \ No newline at end of file