From 5f15d5e2d662e2aad75c17c53ef80dbfebe9b0b8 Mon Sep 17 00:00:00 2001 From: danischm Date: Sun, 23 Jul 2023 20:59:41 +0200 Subject: [PATCH] Refactor application aware routing policy definition --- ...ication_aware_routing_policy_definition.md | 21 +- ...ication_aware_routing_policy_definition.md | 23 +- ...tion_aware_routing_policy_definition.yaml} | 118 +++++- ...ication_aware_routing_policy_definition.go | 23 +- ...on_aware_routing_policy_definition_test.go | 6 +- ...ication_aware_routing_policy_definition.go | 388 ++++++++---------- internal/provider/provider.go | 4 +- ...ication_aware_routing_policy_definition.go | 55 +-- ...on_aware_routing_policy_definition_test.go | 6 +- 9 files changed, 338 insertions(+), 306 deletions(-) rename gen/definitions/{policy_definitions/application_aware_routing.yaml => generic/application_aware_routing_policy_definition.yaml} (72%) diff --git a/docs/data-sources/application_aware_routing_policy_definition.md b/docs/data-sources/application_aware_routing_policy_definition.md index a7d7158c..8dfd8163 100644 --- a/docs/data-sources/application_aware_routing_policy_definition.md +++ b/docs/data-sources/application_aware_routing_policy_definition.md @@ -3,12 +3,12 @@ page_title: "sdwan_application_aware_routing_policy_definition Data Source - terraform-provider-sdwan" subcategory: "Centralized Policies" description: |- - This data source can read the Application Aware Routing policy definition. + This data source can read the Application Aware Routing Policy Definition . --- # sdwan_application_aware_routing_policy_definition (Data Source) -This data source can read the Application Aware Routing policy definition. +This data source can read the Application Aware Routing Policy Definition . ## Example Usage @@ -23,15 +23,14 @@ data "sdwan_application_aware_routing_policy_definition" "example" { ### Required -- `id` (String) The id of the policy definition +- `id` (String) The id of the object ### Read-Only - `description` (String) The description of the policy definition - `name` (String) The name of the policy definition - `sequences` (Attributes List) List of sequences (see [below for nested schema](#nestedatt--sequences)) -- `type` (String) The policy definition type -- `version` (Number) The version of the policy definition +- `version` (Number) The version of the object ### Nested Schema for `sequences` @@ -50,14 +49,14 @@ Read-Only: Read-Only: - `backup_sla_preferred_color` (String) Backup SLA preferred color -- `cloud_sla` (String) Cloud SLA -- `cloud_sla_parameters` (Attributes List) List of cloud SLA parameters (see [below for nested schema](#nestedatt--sequences--action_entries--cloud_sla_parameters)) +- `cloud_sla` (Boolean) Cloud SLA - `counter` (String) Counter name -- `log` (String) Enable logging +- `log` (Boolean) Enable logging +- `sla_class_parameters` (Attributes List) List of SLA class parameters (see [below for nested schema](#nestedatt--sequences--action_entries--sla_class_parameters)) - `type` (String) Type of action entry - -### Nested Schema for `sequences.action_entries.cloud_sla_parameters` + +### Nested Schema for `sequences.action_entries.sla_class_parameters` Read-Only: @@ -66,7 +65,7 @@ Read-Only: - `preferred_color_group_list_version` (Number) Preferred color group list version - `sla_class_list` (String) SLA class list ID - `sla_class_list_version` (Number) SLA class list version -- `type` (String) Type of cloud SLA parameter +- `type` (String) Type of SLA class parameter diff --git a/docs/resources/application_aware_routing_policy_definition.md b/docs/resources/application_aware_routing_policy_definition.md index 6c96b69f..ecd57a32 100644 --- a/docs/resources/application_aware_routing_policy_definition.md +++ b/docs/resources/application_aware_routing_policy_definition.md @@ -3,12 +3,12 @@ page_title: "sdwan_application_aware_routing_policy_definition Resource - terraform-provider-sdwan" subcategory: "Centralized Policies" description: |- - This resource can manage a Application Aware Routing policy definition. + This resource can manage a Application Aware Routing Policy Definition . --- # sdwan_application_aware_routing_policy_definition (Resource) -This resource can manage a Application Aware Routing policy definition. +This resource can manage a Application Aware Routing Policy Definition . ## Example Usage @@ -49,9 +49,8 @@ resource "sdwan_application_aware_routing_policy_definition" "example" { ### Read-Only -- `id` (String) The id of the policy definition -- `type` (String) The policy defintion type -- `version` (Number) The version of the policy definition +- `id` (String) The id of the object +- `version` (Number) The version of the object ### Nested Schema for `sequences` @@ -79,19 +78,17 @@ Required: Optional: - `backup_sla_preferred_color` (String) Backup SLA preferred color -- `cloud_sla` (String) Cloud SLA - - Choices: `` -- `cloud_sla_parameters` (Attributes List) List of cloud SLA parameters (see [below for nested schema](#nestedatt--sequences--action_entries--cloud_sla_parameters)) +- `cloud_sla` (Boolean) Cloud SLA - `counter` (String) Counter name -- `log` (String) Enable logging - - Choices: `` +- `log` (Boolean) Enable logging +- `sla_class_parameters` (Attributes List) List of SLA class parameters (see [below for nested schema](#nestedatt--sequences--action_entries--sla_class_parameters)) - -### Nested Schema for `sequences.action_entries.cloud_sla_parameters` + +### Nested Schema for `sequences.action_entries.sla_class_parameters` Required: -- `type` (String) Type of cloud SLA parameter +- `type` (String) Type of SLA class parameter - Choices: `name`, `preferredColor`, `preferredColorGroup` Optional: diff --git a/gen/definitions/policy_definitions/application_aware_routing.yaml b/gen/definitions/generic/application_aware_routing_policy_definition.yaml similarity index 72% rename from gen/definitions/policy_definitions/application_aware_routing.yaml rename to gen/definitions/generic/application_aware_routing_policy_definition.yaml index c990baa0..c6985833 100644 --- a/gen/definitions/policy_definitions/application_aware_routing.yaml +++ b/gen/definitions/generic/application_aware_routing_policy_definition.yaml @@ -1,9 +1,24 @@ --- -name: Application Aware Routing -type: appRoute +name: Application Aware Routing Policy Definition +rest_endpoint: /template/policy/definition/approute/ +has_version: true +id_attribute: definitionId doc_category: Centralized Policies -skip_templates: [model.go, resource.go, data_source.go] attributes: + - model_name: type + value: appRoute + - model_name: name + tf_name: name + type: String + mandatory: true + description: The name of the policy definition + example: Example + - model_name: description + tf_name: description + type: String + mandatory: true + description: The description of the policy definition + example: My description - model_name: sequences tf_name: sequences type: List @@ -14,12 +29,14 @@ attributes: tf_name: id type: Int64 mandatory: true + id: true description: Sequence ID example: 1 - model_name: sequenceName tf_name: name type: String mandatory: true + id: true description: Sequence name example: Region1 - model_name: sequenceType @@ -39,6 +56,7 @@ attributes: - model_name: field tf_name: type type: String + id: true mandatory: true enum_values: [ @@ -61,27 +79,36 @@ attributes: example: appList - model_name: ref tf_name: application_list_id + conditional_attribute: + name: type + value: appList type: String description: Application list ID example: e3aad846-abb9-425f-aaa8-9ed17b9c8d7c - tf_name: application_list_version tf_only: true - type: Int64 + type: Version description: Application list version exclude_test: true - model_name: ref tf_name: dns_application_list_id + conditional_attribute: + name: type + value: dnsAppList type: String description: DNS Application list ID example: e3aad846-abb9-425f-aaa8-9ed17b9c8d7c exclude_test: true - tf_name: dns_application_list_version tf_only: true - type: Int64 + type: Version description: DNS Application list version exclude_test: true - model_name: value tf_name: dns + conditional_attribute: + name: type + value: dns type: String enum_values: [request, response] description: DNS request or response @@ -89,6 +116,9 @@ attributes: exclude_test: true - model_name: value tf_name: dscp + conditional_attribute: + name: type + value: dscp type: Int64 model_type_string: true description: DSCP value @@ -98,6 +128,9 @@ attributes: exclude_test: true - model_name: value tf_name: plp + conditional_attribute: + name: type + value: plp type: String enum_values: [low, high] description: PLP @@ -105,6 +138,9 @@ attributes: exclude_test: true - model_name: value tf_name: protocol + conditional_attribute: + name: type + value: protocol type: Int64 model_type_string: true description: IP Protocol @@ -114,23 +150,32 @@ attributes: exclude_test: true - model_name: ref tf_name: source_data_prefix_list_id + conditional_attribute: + name: type + value: sourceDataPrefixList type: String description: Source Data Prefix list ID example: 7d97276b-321c-4d0c-870e-342bbcd51011 exclude_test: true - tf_name: source_data_prefix_list_version tf_only: true - type: Int64 + type: Version description: Source Data Prefix list version exclude_test: true - model_name: value tf_name: source_ip + conditional_attribute: + name: type + value: sourceIp type: String description: Source IP example: 10.0.0.0/12 exclude_test: true - model_name: value tf_name: source_port + conditional_attribute: + name: type + value: sourcePort type: Int64 model_type_string: true description: Source port @@ -140,23 +185,32 @@ attributes: exclude_test: true - model_name: ref tf_name: destination_data_prefix_list_id + conditional_attribute: + name: type + value: destinationDataPrefixList type: String description: Destination Data Prefix list ID example: 7d97276b-321c-4d0c-870e-342bbcd51011 exclude_test: true - tf_name: destination_data_prefix_list_version tf_only: true - type: Int64 + type: Version description: Destination Data Prefix list version exclude_test: true - model_name: value tf_name: destination_ip + conditional_attribute: + name: type + value: destinationIp type: String description: Destination IP example: 10.0.0.0/12 exclude_test: true - model_name: value tf_name: destination_port + conditional_attribute: + name: type + value: destinationPort type: Int64 model_type_string: true description: Destination port @@ -166,6 +220,9 @@ attributes: exclude_test: true - model_name: value tf_name: destination_region + conditional_attribute: + name: type + value: destinationRegion type: String enum_values: [primary-region, secondary-region, other-region] description: Destination region @@ -173,6 +230,9 @@ attributes: exclude_test: true - model_name: value tf_name: traffic_to + conditional_attribute: + name: type + value: trafficTo type: String enum_values: [access, core, service] description: Traffic to @@ -186,6 +246,7 @@ attributes: - model_name: type tf_name: type type: String + id: true mandatory: true enum_values: [backupSlaPreferredColor, count, log, slaClass, cloudSaas] @@ -193,66 +254,91 @@ attributes: example: backupSlaPreferredColor - model_name: parameter tf_name: backup_sla_preferred_color + conditional_attribute: + name: type + value: backupSlaPreferredColor type: String description: Backup SLA preferred color example: bronze - model_name: parameter tf_name: counter + conditional_attribute: + name: type + value: count type: String description: Counter name example: count1 exclude_test: true - model_name: parameter tf_name: log - type: String - enum_values: [""] + conditional_attribute: + name: type + value: log + type: Bool + bool_empty_value: true description: Enable logging example: "" exclude_test: true - model_name: parameter tf_name: cloud_sla - type: String - enum_values: [""] + conditional_attribute: + name: type + value: cloudSaas + type: Bool + bool_empty_string: true description: Cloud SLA example: "" exclude_test: true - model_name: parameter - tf_name: cloud_sla_parameters + tf_name: sla_class_parameters + conditional_attribute: + name: type + value: slaClass type: List - description: List of cloud SLA parameters + description: List of SLA class parameters exclude_test: true attributes: - model_name: field tf_name: type type: String + id: true mandatory: true enum_values: [name, preferredColor, preferredColorGroup] - description: Type of cloud SLA parameter + description: Type of SLA class parameter example: name - model_name: ref tf_name: sla_class_list + conditional_attribute: + name: type + value: name type: String description: SLA class list ID example: 71920ba0-46e7-411a-a730-387414aabc08 exclude_test: true - tf_name: sla_class_list_version tf_only: true - type: Int64 + type: Version description: SLA class list version exclude_test: true - model_name: ref tf_name: preferred_color_group_list + conditional_attribute: + name: type + value: preferredColorGroup type: String description: Preferred color group list ID example: 45bd33f6-f177-42f3-8aa6-60a62dfd6dd2 exclude_test: true - tf_name: preferred_color_group_list_version tf_only: true - type: Int64 + type: Version description: Preferred color group list version exclude_test: true - model_name: value tf_name: preferred_color + conditional_attribute: + name: type + value: preferredColor type: String description: preferred color example: bronze diff --git a/internal/provider/data_source_sdwan_application_aware_routing_policy_definition.go b/internal/provider/data_source_sdwan_application_aware_routing_policy_definition.go index c597e681..5a48465d 100644 --- a/internal/provider/data_source_sdwan_application_aware_routing_policy_definition.go +++ b/internal/provider/data_source_sdwan_application_aware_routing_policy_definition.go @@ -50,19 +50,15 @@ func (d *ApplicationAwareRoutingPolicyDefinitionDataSource) Metadata(_ context.C func (d *ApplicationAwareRoutingPolicyDefinitionDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { resp.Schema = schema.Schema{ // This description is used by the documentation generator and the language server. - MarkdownDescription: "This data source can read the Application Aware Routing policy definition.", + MarkdownDescription: "This data source can read the Application Aware Routing Policy Definition .", Attributes: map[string]schema.Attribute{ "id": schema.StringAttribute{ - MarkdownDescription: "The id of the policy definition", + MarkdownDescription: "The id of the object", Required: true, }, "version": schema.Int64Attribute{ - MarkdownDescription: "The version of the policy definition", - Computed: true, - }, - "type": schema.StringAttribute{ - MarkdownDescription: "The policy definition type", + MarkdownDescription: "The version of the object", Computed: true, }, "name": schema.StringAttribute{ @@ -191,21 +187,21 @@ func (d *ApplicationAwareRoutingPolicyDefinitionDataSource) Schema(ctx context.C MarkdownDescription: "Counter name", Computed: true, }, - "log": schema.StringAttribute{ + "log": schema.BoolAttribute{ MarkdownDescription: "Enable logging", Computed: true, }, - "cloud_sla": schema.StringAttribute{ + "cloud_sla": schema.BoolAttribute{ MarkdownDescription: "Cloud SLA", Computed: true, }, - "cloud_sla_parameters": schema.ListNestedAttribute{ - MarkdownDescription: "List of cloud SLA parameters", + "sla_class_parameters": schema.ListNestedAttribute{ + MarkdownDescription: "List of SLA class parameters", Computed: true, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ "type": schema.StringAttribute{ - MarkdownDescription: "Type of cloud SLA parameter", + MarkdownDescription: "Type of SLA class parameter", Computed: true, }, "sla_class_list": schema.StringAttribute{ @@ -250,7 +246,7 @@ func (d *ApplicationAwareRoutingPolicyDefinitionDataSource) Configure(_ context. } func (d *ApplicationAwareRoutingPolicyDefinitionDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - var config ApplicationAwareRouting + var config ApplicationAwareRoutingPolicyDefinition // Read config diags := req.Config.Get(ctx, &config) @@ -268,7 +264,6 @@ func (d *ApplicationAwareRoutingPolicyDefinitionDataSource) Read(ctx context.Con } config.fromBody(ctx, res) - config.updateVersions(ctx, config) tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", config.Id.ValueString())) diff --git a/internal/provider/data_source_sdwan_application_aware_routing_policy_definition_test.go b/internal/provider/data_source_sdwan_application_aware_routing_policy_definition_test.go index bfae291c..8dbcabc5 100644 --- a/internal/provider/data_source_sdwan_application_aware_routing_policy_definition_test.go +++ b/internal/provider/data_source_sdwan_application_aware_routing_policy_definition_test.go @@ -33,6 +33,8 @@ func TestAccDataSourceSdwanApplicationAwareRoutingPolicyDefinition(t *testing.T) { Config: testAccDataSourceSdwanApplicationAwareRoutingPolicyDefinitionConfig, Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.sdwan_application_aware_routing_policy_definition.test", "name", "Example"), + resource.TestCheckResourceAttr("data.sdwan_application_aware_routing_policy_definition.test", "description", "My description"), resource.TestCheckResourceAttr("data.sdwan_application_aware_routing_policy_definition.test", "sequences.0.id", "1"), resource.TestCheckResourceAttr("data.sdwan_application_aware_routing_policy_definition.test", "sequences.0.name", "Region1"), resource.TestCheckResourceAttr("data.sdwan_application_aware_routing_policy_definition.test", "sequences.0.ip_type", "ipv4"), @@ -49,8 +51,8 @@ func TestAccDataSourceSdwanApplicationAwareRoutingPolicyDefinition(t *testing.T) const testAccDataSourceSdwanApplicationAwareRoutingPolicyDefinitionConfig = ` resource "sdwan_application_aware_routing_policy_definition" "test" { - name = "TF_TEST_MIN" - description = "Terraform integration test" + name = "Example" + description = "My description" sequences = [{ id = 1 name = "Region1" diff --git a/internal/provider/model_sdwan_application_aware_routing_policy_definition.go b/internal/provider/model_sdwan_application_aware_routing_policy_definition.go index c56ad09b..decc4b36 100644 --- a/internal/provider/model_sdwan_application_aware_routing_policy_definition.go +++ b/internal/provider/model_sdwan_application_aware_routing_policy_definition.go @@ -28,24 +28,23 @@ import ( "github.com/tidwall/sjson" ) -type ApplicationAwareRouting struct { - Id types.String `tfsdk:"id"` - Version types.Int64 `tfsdk:"version"` - Type types.String `tfsdk:"type"` - Name types.String `tfsdk:"name"` - Description types.String `tfsdk:"description"` - Sequences []ApplicationAwareRoutingSequences `tfsdk:"sequences"` +type ApplicationAwareRoutingPolicyDefinition struct { + Id types.String `tfsdk:"id"` + Version types.Int64 `tfsdk:"version"` + Name types.String `tfsdk:"name"` + Description types.String `tfsdk:"description"` + Sequences []ApplicationAwareRoutingPolicyDefinitionSequences `tfsdk:"sequences"` } -type ApplicationAwareRoutingSequences struct { - Id types.Int64 `tfsdk:"id"` - Name types.String `tfsdk:"name"` - IpType types.String `tfsdk:"ip_type"` - MatchEntries []ApplicationAwareRoutingSequencesMatchEntries `tfsdk:"match_entries"` - ActionEntries []ApplicationAwareRoutingSequencesActionEntries `tfsdk:"action_entries"` +type ApplicationAwareRoutingPolicyDefinitionSequences struct { + Id types.Int64 `tfsdk:"id"` + Name types.String `tfsdk:"name"` + IpType types.String `tfsdk:"ip_type"` + MatchEntries []ApplicationAwareRoutingPolicyDefinitionSequencesMatchEntries `tfsdk:"match_entries"` + ActionEntries []ApplicationAwareRoutingPolicyDefinitionSequencesActionEntries `tfsdk:"action_entries"` } -type ApplicationAwareRoutingSequencesMatchEntries struct { +type ApplicationAwareRoutingPolicyDefinitionSequencesMatchEntries struct { Type types.String `tfsdk:"type"` ApplicationListId types.String `tfsdk:"application_list_id"` ApplicationListVersion types.Int64 `tfsdk:"application_list_version"` @@ -66,16 +65,16 @@ type ApplicationAwareRoutingSequencesMatchEntries struct { DestinationRegion types.String `tfsdk:"destination_region"` TrafficTo types.String `tfsdk:"traffic_to"` } -type ApplicationAwareRoutingSequencesActionEntries struct { - Type types.String `tfsdk:"type"` - BackupSlaPreferredColor types.String `tfsdk:"backup_sla_preferred_color"` - Counter types.String `tfsdk:"counter"` - Log types.String `tfsdk:"log"` - CloudSla types.String `tfsdk:"cloud_sla"` - CloudSlaParameters []ApplicationAwareRoutingSequencesActionEntriesCloudSlaParameters `tfsdk:"cloud_sla_parameters"` +type ApplicationAwareRoutingPolicyDefinitionSequencesActionEntries struct { + Type types.String `tfsdk:"type"` + BackupSlaPreferredColor types.String `tfsdk:"backup_sla_preferred_color"` + Counter types.String `tfsdk:"counter"` + Log types.Bool `tfsdk:"log"` + CloudSla types.Bool `tfsdk:"cloud_sla"` + SlaClassParameters []ApplicationAwareRoutingPolicyDefinitionSequencesActionEntriesSlaClassParameters `tfsdk:"sla_class_parameters"` } -type ApplicationAwareRoutingSequencesActionEntriesCloudSlaParameters struct { +type ApplicationAwareRoutingPolicyDefinitionSequencesActionEntriesSlaClassParameters struct { Type types.String `tfsdk:"type"` SlaClassList types.String `tfsdk:"sla_class_list"` SlaClassListVersion types.Int64 `tfsdk:"sla_class_list_version"` @@ -84,17 +83,17 @@ type ApplicationAwareRoutingSequencesActionEntriesCloudSlaParameters struct { PreferredColor types.String `tfsdk:"preferred_color"` } -func (data ApplicationAwareRouting) getType() string { - return "appRoute" -} - -func (data ApplicationAwareRouting) toBody(ctx context.Context) string { - body, _ := sjson.Set("", "name", data.Name.ValueString()) - body, _ = sjson.Set(body, "description", data.Description.ValueString()) +func (data ApplicationAwareRoutingPolicyDefinition) toBody(ctx context.Context) string { + body := "" body, _ = sjson.Set(body, "type", "appRoute") - path := "" + if !data.Name.IsNull() { + body, _ = sjson.Set(body, "name", data.Name.ValueString()) + } + if !data.Description.IsNull() { + body, _ = sjson.Set(body, "description", data.Description.ValueString()) + } if len(data.Sequences) > 0 { - body, _ = sjson.Set(body, path+"sequences", []interface{}{}) + body, _ = sjson.Set(body, "sequences", []interface{}{}) for _, item := range data.Sequences { itemBody := "" if !item.Id.IsNull() { @@ -114,46 +113,46 @@ func (data ApplicationAwareRouting) toBody(ctx context.Context) string { if !childItem.Type.IsNull() { itemChildBody, _ = sjson.Set(itemChildBody, "field", childItem.Type.ValueString()) } - if !childItem.ApplicationListId.IsNull() { + if !childItem.ApplicationListId.IsNull() && childItem.Type.ValueString() == "appList" { itemChildBody, _ = sjson.Set(itemChildBody, "ref", childItem.ApplicationListId.ValueString()) } - if !childItem.DnsApplicationListId.IsNull() { + if !childItem.DnsApplicationListId.IsNull() && childItem.Type.ValueString() == "dnsAppList" { itemChildBody, _ = sjson.Set(itemChildBody, "ref", childItem.DnsApplicationListId.ValueString()) } - if !childItem.Dns.IsNull() { + if !childItem.Dns.IsNull() && childItem.Type.ValueString() == "dns" { itemChildBody, _ = sjson.Set(itemChildBody, "value", childItem.Dns.ValueString()) } - if !childItem.Dscp.IsNull() { + if !childItem.Dscp.IsNull() && childItem.Type.ValueString() == "dscp" { itemChildBody, _ = sjson.Set(itemChildBody, "value", fmt.Sprint(childItem.Dscp.ValueInt64())) } - if !childItem.Plp.IsNull() { + if !childItem.Plp.IsNull() && childItem.Type.ValueString() == "plp" { itemChildBody, _ = sjson.Set(itemChildBody, "value", childItem.Plp.ValueString()) } - if !childItem.Protocol.IsNull() { + if !childItem.Protocol.IsNull() && childItem.Type.ValueString() == "protocol" { itemChildBody, _ = sjson.Set(itemChildBody, "value", fmt.Sprint(childItem.Protocol.ValueInt64())) } - if !childItem.SourceDataPrefixListId.IsNull() { + if !childItem.SourceDataPrefixListId.IsNull() && childItem.Type.ValueString() == "sourceDataPrefixList" { itemChildBody, _ = sjson.Set(itemChildBody, "ref", childItem.SourceDataPrefixListId.ValueString()) } - if !childItem.SourceIp.IsNull() { + if !childItem.SourceIp.IsNull() && childItem.Type.ValueString() == "sourceIp" { itemChildBody, _ = sjson.Set(itemChildBody, "value", childItem.SourceIp.ValueString()) } - if !childItem.SourcePort.IsNull() { + if !childItem.SourcePort.IsNull() && childItem.Type.ValueString() == "sourcePort" { itemChildBody, _ = sjson.Set(itemChildBody, "value", fmt.Sprint(childItem.SourcePort.ValueInt64())) } - if !childItem.DestinationDataPrefixListId.IsNull() { + if !childItem.DestinationDataPrefixListId.IsNull() && childItem.Type.ValueString() == "destinationDataPrefixList" { itemChildBody, _ = sjson.Set(itemChildBody, "ref", childItem.DestinationDataPrefixListId.ValueString()) } - if !childItem.DestinationIp.IsNull() { + if !childItem.DestinationIp.IsNull() && childItem.Type.ValueString() == "destinationIp" { itemChildBody, _ = sjson.Set(itemChildBody, "value", childItem.DestinationIp.ValueString()) } - if !childItem.DestinationPort.IsNull() { + if !childItem.DestinationPort.IsNull() && childItem.Type.ValueString() == "destinationPort" { itemChildBody, _ = sjson.Set(itemChildBody, "value", fmt.Sprint(childItem.DestinationPort.ValueInt64())) } - if !childItem.DestinationRegion.IsNull() { + if !childItem.DestinationRegion.IsNull() && childItem.Type.ValueString() == "destinationRegion" { itemChildBody, _ = sjson.Set(itemChildBody, "value", childItem.DestinationRegion.ValueString()) } - if !childItem.TrafficTo.IsNull() { + if !childItem.TrafficTo.IsNull() && childItem.Type.ValueString() == "trafficTo" { itemChildBody, _ = sjson.Set(itemChildBody, "value", childItem.TrafficTo.ValueString()) } itemBody, _ = sjson.SetRaw(itemBody, "match.entries.-1", itemChildBody) @@ -166,32 +165,40 @@ func (data ApplicationAwareRouting) toBody(ctx context.Context) string { if !childItem.Type.IsNull() { itemChildBody, _ = sjson.Set(itemChildBody, "type", childItem.Type.ValueString()) } - if !childItem.BackupSlaPreferredColor.IsNull() { + if !childItem.BackupSlaPreferredColor.IsNull() && childItem.Type.ValueString() == "backupSlaPreferredColor" { itemChildBody, _ = sjson.Set(itemChildBody, "parameter", childItem.BackupSlaPreferredColor.ValueString()) } - if !childItem.Counter.IsNull() { + if !childItem.Counter.IsNull() && childItem.Type.ValueString() == "count" { itemChildBody, _ = sjson.Set(itemChildBody, "parameter", childItem.Counter.ValueString()) } - if !childItem.Log.IsNull() { - itemChildBody, _ = sjson.Set(itemChildBody, "parameter", childItem.Log.ValueString()) + if !childItem.Log.IsNull() && childItem.Type.ValueString() == "log" { + if false && childItem.Log.ValueBool() { + itemChildBody, _ = sjson.Set(itemChildBody, "parameter", "") + } else { + itemChildBody, _ = sjson.Set(itemChildBody, "parameter", childItem.Log.ValueBool()) + } } - if !childItem.CloudSla.IsNull() { - itemChildBody, _ = sjson.Set(itemChildBody, "parameter", childItem.CloudSla.ValueString()) + if !childItem.CloudSla.IsNull() && childItem.Type.ValueString() == "cloudSaas" { + if true && childItem.CloudSla.ValueBool() { + itemChildBody, _ = sjson.Set(itemChildBody, "parameter", "") + } else { + itemChildBody, _ = sjson.Set(itemChildBody, "parameter", childItem.CloudSla.ValueBool()) + } } - if len(childItem.CloudSlaParameters) > 0 { + if len(childItem.SlaClassParameters) > 0 && childItem.Type.ValueString() == "slaClass" { itemChildBody, _ = sjson.Set(itemChildBody, "parameter", []interface{}{}) - for _, childChildItem := range childItem.CloudSlaParameters { + for _, childChildItem := range childItem.SlaClassParameters { itemChildChildBody := "" if !childChildItem.Type.IsNull() { itemChildChildBody, _ = sjson.Set(itemChildChildBody, "field", childChildItem.Type.ValueString()) } - if !childChildItem.SlaClassList.IsNull() { + if !childChildItem.SlaClassList.IsNull() && childChildItem.Type.ValueString() == "name" { itemChildChildBody, _ = sjson.Set(itemChildChildBody, "ref", childChildItem.SlaClassList.ValueString()) } - if !childChildItem.PreferredColorGroupList.IsNull() { + if !childChildItem.PreferredColorGroupList.IsNull() && childChildItem.Type.ValueString() == "preferredColorGroup" { itemChildChildBody, _ = sjson.Set(itemChildChildBody, "ref", childChildItem.PreferredColorGroupList.ValueString()) } - if !childChildItem.PreferredColor.IsNull() { + if !childChildItem.PreferredColor.IsNull() && childChildItem.Type.ValueString() == "preferredColor" { itemChildChildBody, _ = sjson.Set(itemChildChildBody, "value", childChildItem.PreferredColor.ValueString()) } itemChildBody, _ = sjson.SetRaw(itemChildBody, "parameter.-1", itemChildChildBody) @@ -200,13 +207,13 @@ func (data ApplicationAwareRouting) toBody(ctx context.Context) string { itemBody, _ = sjson.SetRaw(itemBody, "actions.-1", itemChildBody) } } - body, _ = sjson.SetRaw(body, path+"sequences.-1", itemBody) + body, _ = sjson.SetRaw(body, "sequences.-1", itemBody) } } return body } -func (data *ApplicationAwareRouting) fromBody(ctx context.Context, res gjson.Result) { +func (data *ApplicationAwareRoutingPolicyDefinition) fromBody(ctx context.Context, res gjson.Result) { if value := res.Get("name"); value.Exists() { data.Name = types.StringValue(value.String()) } else { @@ -217,16 +224,10 @@ func (data *ApplicationAwareRouting) fromBody(ctx context.Context, res gjson.Res } else { data.Description = types.StringNull() } - if value := res.Get("type"); value.Exists() { - data.Type = types.StringValue(value.String()) - } else { - data.Type = types.StringNull() - } - path := "" - if value := res.Get(path + "sequences"); value.Exists() { - data.Sequences = make([]ApplicationAwareRoutingSequences, 0) + if value := res.Get("sequences"); value.Exists() { + data.Sequences = make([]ApplicationAwareRoutingPolicyDefinitionSequences, 0) value.ForEach(func(k, v gjson.Result) bool { - item := ApplicationAwareRoutingSequences{} + item := ApplicationAwareRoutingPolicyDefinitionSequences{} if cValue := v.Get("sequenceId"); cValue.Exists() { item.Id = types.Int64Value(cValue.Int()) } else { @@ -243,80 +244,80 @@ func (data *ApplicationAwareRouting) fromBody(ctx context.Context, res gjson.Res item.IpType = types.StringNull() } if cValue := v.Get("match.entries"); cValue.Exists() { - item.MatchEntries = make([]ApplicationAwareRoutingSequencesMatchEntries, 0) + item.MatchEntries = make([]ApplicationAwareRoutingPolicyDefinitionSequencesMatchEntries, 0) cValue.ForEach(func(ck, cv gjson.Result) bool { - cItem := ApplicationAwareRoutingSequencesMatchEntries{} + cItem := ApplicationAwareRoutingPolicyDefinitionSequencesMatchEntries{} if ccValue := cv.Get("field"); ccValue.Exists() { cItem.Type = types.StringValue(ccValue.String()) } else { cItem.Type = types.StringNull() } - if ccValue := cv.Get("ref"); cItem.Type.ValueString() == "appList" && ccValue.Exists() { + if ccValue := cv.Get("ref"); ccValue.Exists() && cItem.Type.ValueString() == "appList" { cItem.ApplicationListId = types.StringValue(ccValue.String()) } else { cItem.ApplicationListId = types.StringNull() } - if ccValue := cv.Get("ref"); cItem.Type.ValueString() == "dnsAppList" && ccValue.Exists() { + if ccValue := cv.Get("ref"); ccValue.Exists() && cItem.Type.ValueString() == "dnsAppList" { cItem.DnsApplicationListId = types.StringValue(ccValue.String()) } else { cItem.DnsApplicationListId = types.StringNull() } - if ccValue := cv.Get("value"); cItem.Type.ValueString() == "dns" && ccValue.Exists() { + if ccValue := cv.Get("value"); ccValue.Exists() && cItem.Type.ValueString() == "dns" { cItem.Dns = types.StringValue(ccValue.String()) } else { cItem.Dns = types.StringNull() } - if ccValue := cv.Get("value"); cItem.Type.ValueString() == "dscp" && ccValue.Exists() { + if ccValue := cv.Get("value"); ccValue.Exists() && cItem.Type.ValueString() == "dscp" { cItem.Dscp = types.Int64Value(ccValue.Int()) } else { cItem.Dscp = types.Int64Null() } - if ccValue := cv.Get("value"); cItem.Type.ValueString() == "plp" && ccValue.Exists() { + if ccValue := cv.Get("value"); ccValue.Exists() && cItem.Type.ValueString() == "plp" { cItem.Plp = types.StringValue(ccValue.String()) } else { cItem.Plp = types.StringNull() } - if ccValue := cv.Get("value"); cItem.Type.ValueString() == "protocol" && ccValue.Exists() { + if ccValue := cv.Get("value"); ccValue.Exists() && cItem.Type.ValueString() == "protocol" { cItem.Protocol = types.Int64Value(ccValue.Int()) } else { cItem.Protocol = types.Int64Null() } - if ccValue := cv.Get("ref"); cItem.Type.ValueString() == "sourceDataPrefixList" && ccValue.Exists() { + if ccValue := cv.Get("ref"); ccValue.Exists() && cItem.Type.ValueString() == "sourceDataPrefixList" { cItem.SourceDataPrefixListId = types.StringValue(ccValue.String()) } else { cItem.SourceDataPrefixListId = types.StringNull() } - if ccValue := cv.Get("value"); cItem.Type.ValueString() == "sourceIp" && ccValue.Exists() { + if ccValue := cv.Get("value"); ccValue.Exists() && cItem.Type.ValueString() == "sourceIp" { cItem.SourceIp = types.StringValue(ccValue.String()) } else { cItem.SourceIp = types.StringNull() } - if ccValue := cv.Get("value"); cItem.Type.ValueString() == "sourcePort" && ccValue.Exists() { + if ccValue := cv.Get("value"); ccValue.Exists() && cItem.Type.ValueString() == "sourcePort" { cItem.SourcePort = types.Int64Value(ccValue.Int()) } else { cItem.SourcePort = types.Int64Null() } - if ccValue := cv.Get("ref"); cItem.Type.ValueString() == "destinationDataPrefixList" && ccValue.Exists() { + if ccValue := cv.Get("ref"); ccValue.Exists() && cItem.Type.ValueString() == "destinationDataPrefixList" { cItem.DestinationDataPrefixListId = types.StringValue(ccValue.String()) } else { cItem.DestinationDataPrefixListId = types.StringNull() } - if ccValue := cv.Get("value"); cItem.Type.ValueString() == "destinationIp" && ccValue.Exists() { + if ccValue := cv.Get("value"); ccValue.Exists() && cItem.Type.ValueString() == "destinationIp" { cItem.DestinationIp = types.StringValue(ccValue.String()) } else { cItem.DestinationIp = types.StringNull() } - if ccValue := cv.Get("value"); cItem.Type.ValueString() == "destinationPort" && ccValue.Exists() { + if ccValue := cv.Get("value"); ccValue.Exists() && cItem.Type.ValueString() == "destinationPort" { cItem.DestinationPort = types.Int64Value(ccValue.Int()) } else { cItem.DestinationPort = types.Int64Null() } - if ccValue := cv.Get("value"); cItem.Type.ValueString() == "destinationRegion" && ccValue.Exists() { + if ccValue := cv.Get("value"); ccValue.Exists() && cItem.Type.ValueString() == "destinationRegion" { cItem.DestinationRegion = types.StringValue(ccValue.String()) } else { cItem.DestinationRegion = types.StringNull() } - if ccValue := cv.Get("value"); cItem.Type.ValueString() == "trafficTo" && ccValue.Exists() { + if ccValue := cv.Get("value"); ccValue.Exists() && cItem.Type.ValueString() == "trafficTo" { cItem.TrafficTo = types.StringValue(ccValue.String()) } else { cItem.TrafficTo = types.StringNull() @@ -326,59 +327,67 @@ func (data *ApplicationAwareRouting) fromBody(ctx context.Context, res gjson.Res }) } if cValue := v.Get("actions"); cValue.Exists() { - item.ActionEntries = make([]ApplicationAwareRoutingSequencesActionEntries, 0) + item.ActionEntries = make([]ApplicationAwareRoutingPolicyDefinitionSequencesActionEntries, 0) cValue.ForEach(func(ck, cv gjson.Result) bool { - cItem := ApplicationAwareRoutingSequencesActionEntries{} + cItem := ApplicationAwareRoutingPolicyDefinitionSequencesActionEntries{} if ccValue := cv.Get("type"); ccValue.Exists() { cItem.Type = types.StringValue(ccValue.String()) } else { cItem.Type = types.StringNull() } - if ccValue := cv.Get("parameter"); cItem.Type.ValueString() == "backupSlaPreferredColor" && ccValue.Exists() { + if ccValue := cv.Get("parameter"); ccValue.Exists() && cItem.Type.ValueString() == "backupSlaPreferredColor" { cItem.BackupSlaPreferredColor = types.StringValue(ccValue.String()) } else { cItem.BackupSlaPreferredColor = types.StringNull() } - if ccValue := cv.Get("parameter"); cItem.Type.ValueString() == "count" && ccValue.Exists() { + if ccValue := cv.Get("parameter"); ccValue.Exists() && cItem.Type.ValueString() == "count" { cItem.Counter = types.StringValue(ccValue.String()) } else { cItem.Counter = types.StringNull() } - if ccValue := cv.Get("parameter"); cItem.Type.ValueString() == "log" && ccValue.Exists() { - cItem.Log = types.StringValue(ccValue.String()) + if ccValue := cv.Get("parameter"); ccValue.Exists() && cItem.Type.ValueString() == "log" { + if false && ccValue.String() == "" { + cItem.Log = types.BoolValue(true) + } else { + cItem.Log = types.BoolValue(ccValue.Bool()) + } } else { - cItem.Log = types.StringNull() + cItem.Log = types.BoolNull() } - if ccValue := cv.Get("parameter"); cItem.Type.ValueString() == "cloudSaas" && ccValue.Exists() { - cItem.CloudSla = types.StringValue(ccValue.String()) + if ccValue := cv.Get("parameter"); ccValue.Exists() && cItem.Type.ValueString() == "cloudSaas" { + if true && ccValue.String() == "" { + cItem.CloudSla = types.BoolValue(true) + } else { + cItem.CloudSla = types.BoolValue(ccValue.Bool()) + } } else { - cItem.CloudSla = types.StringNull() + cItem.CloudSla = types.BoolNull() } - if ccValue := cv.Get("parameter"); cItem.Type.ValueString() == "slaClass" && ccValue.Exists() { - cItem.CloudSlaParameters = make([]ApplicationAwareRoutingSequencesActionEntriesCloudSlaParameters, 0) + if ccValue := cv.Get("parameter"); ccValue.Exists() && cItem.Type.ValueString() == "slaClass" { + cItem.SlaClassParameters = make([]ApplicationAwareRoutingPolicyDefinitionSequencesActionEntriesSlaClassParameters, 0) ccValue.ForEach(func(cck, ccv gjson.Result) bool { - ccItem := ApplicationAwareRoutingSequencesActionEntriesCloudSlaParameters{} + ccItem := ApplicationAwareRoutingPolicyDefinitionSequencesActionEntriesSlaClassParameters{} if cccValue := ccv.Get("field"); cccValue.Exists() { ccItem.Type = types.StringValue(cccValue.String()) } else { ccItem.Type = types.StringNull() } - if cccValue := ccv.Get("ref"); ccItem.Type.ValueString() == "name" && cccValue.Exists() { + if cccValue := ccv.Get("ref"); cccValue.Exists() && ccItem.Type.ValueString() == "name" { ccItem.SlaClassList = types.StringValue(cccValue.String()) } else { ccItem.SlaClassList = types.StringNull() } - if cccValue := ccv.Get("ref"); ccItem.Type.ValueString() == "preferredColorGroup" && cccValue.Exists() { + if cccValue := ccv.Get("ref"); cccValue.Exists() && ccItem.Type.ValueString() == "preferredColorGroup" { ccItem.PreferredColorGroupList = types.StringValue(cccValue.String()) } else { ccItem.PreferredColorGroupList = types.StringNull() } - if cccValue := ccv.Get("value"); ccItem.Type.ValueString() == "preferredColor" && cccValue.Exists() { + if cccValue := ccv.Get("value"); cccValue.Exists() && ccItem.Type.ValueString() == "preferredColor" { ccItem.PreferredColor = types.StringValue(cccValue.String()) } else { ccItem.PreferredColor = types.StringNull() } - cItem.CloudSlaParameters = append(cItem.CloudSlaParameters, ccItem) + cItem.SlaClassParameters = append(cItem.SlaClassParameters, ccItem) return true }) } @@ -390,9 +399,12 @@ func (data *ApplicationAwareRouting) fromBody(ctx context.Context, res gjson.Res return true }) } + + data.updateVersions(ctx) + } -func (data *ApplicationAwareRouting) hasChanges(ctx context.Context, state *ApplicationAwareRouting) bool { +func (data *ApplicationAwareRoutingPolicyDefinition) hasChanges(ctx context.Context, state *ApplicationAwareRoutingPolicyDefinition) bool { hasChanges := false if !data.Name.Equal(state.Name) { hasChanges = true @@ -483,20 +495,20 @@ func (data *ApplicationAwareRouting) hasChanges(ctx context.Context, state *Appl if !data.Sequences[i].ActionEntries[ii].CloudSla.Equal(state.Sequences[i].ActionEntries[ii].CloudSla) { hasChanges = true } - if len(data.Sequences[i].ActionEntries[ii].CloudSlaParameters) != len(state.Sequences[i].ActionEntries[ii].CloudSlaParameters) { + if len(data.Sequences[i].ActionEntries[ii].SlaClassParameters) != len(state.Sequences[i].ActionEntries[ii].SlaClassParameters) { hasChanges = true } else { - for iii := range data.Sequences[i].ActionEntries[ii].CloudSlaParameters { - if !data.Sequences[i].ActionEntries[ii].CloudSlaParameters[iii].Type.Equal(state.Sequences[i].ActionEntries[ii].CloudSlaParameters[iii].Type) { + for iii := range data.Sequences[i].ActionEntries[ii].SlaClassParameters { + if !data.Sequences[i].ActionEntries[ii].SlaClassParameters[iii].Type.Equal(state.Sequences[i].ActionEntries[ii].SlaClassParameters[iii].Type) { hasChanges = true } - if !data.Sequences[i].ActionEntries[ii].CloudSlaParameters[iii].SlaClassList.Equal(state.Sequences[i].ActionEntries[ii].CloudSlaParameters[iii].SlaClassList) { + if !data.Sequences[i].ActionEntries[ii].SlaClassParameters[iii].SlaClassList.Equal(state.Sequences[i].ActionEntries[ii].SlaClassParameters[iii].SlaClassList) { hasChanges = true } - if !data.Sequences[i].ActionEntries[ii].CloudSlaParameters[iii].PreferredColorGroupList.Equal(state.Sequences[i].ActionEntries[ii].CloudSlaParameters[iii].PreferredColorGroupList) { + if !data.Sequences[i].ActionEntries[ii].SlaClassParameters[iii].PreferredColorGroupList.Equal(state.Sequences[i].ActionEntries[ii].SlaClassParameters[iii].PreferredColorGroupList) { hasChanges = true } - if !data.Sequences[i].ActionEntries[ii].CloudSlaParameters[iii].PreferredColor.Equal(state.Sequences[i].ActionEntries[ii].CloudSlaParameters[iii].PreferredColor) { + if !data.Sequences[i].ActionEntries[ii].SlaClassParameters[iii].PreferredColor.Equal(state.Sequences[i].ActionEntries[ii].SlaClassParameters[iii].PreferredColor) { hasChanges = true } } @@ -508,119 +520,79 @@ func (data *ApplicationAwareRouting) hasChanges(ctx context.Context, state *Appl return hasChanges } -func (data *ApplicationAwareRouting) getMatchApplicationListVersion(ctx context.Context, name string, id int64) types.Int64 { - for _, item := range data.Sequences { - if item.Name.ValueString() == name && item.Id.ValueInt64() == id { - for _, cItem := range item.MatchEntries { - if cItem.Type.ValueString() == "appList" { - return cItem.ApplicationListVersion - } +func (data *ApplicationAwareRoutingPolicyDefinition) updateVersions(ctx context.Context) { + state := *data + for i := range data.Sequences { + dataKeys := [...]string{fmt.Sprintf("%v", data.Sequences[i].Id.ValueInt64()), fmt.Sprintf("%v", data.Sequences[i].Name.ValueString())} + stateIndex := -1 + for j := range state.Sequences { + stateKeys := [...]string{fmt.Sprintf("%v", state.Sequences[j].Id.ValueInt64()), fmt.Sprintf("%v", state.Sequences[j].Name.ValueString())} + if dataKeys == stateKeys { + stateIndex = j + break } } - } - return types.Int64Null() -} - -func (data *ApplicationAwareRouting) getMatchDnsApplicationListVersion(ctx context.Context, name string, id int64) types.Int64 { - for _, item := range data.Sequences { - if item.Name.ValueString() == name && item.Id.ValueInt64() == id { - for _, cItem := range item.MatchEntries { - if cItem.Type.ValueString() == "dnsAppList" { - return cItem.DnsApplicationListVersion + for ii := range data.Sequences[i].MatchEntries { + cDataKeys := [...]string{fmt.Sprintf("%v", data.Sequences[i].MatchEntries[ii].Type.ValueString())} + cStateIndex := -1 + for jj := range state.Sequences[stateIndex].MatchEntries { + cStateKeys := [...]string{fmt.Sprintf("%v", state.Sequences[stateIndex].MatchEntries[jj].Type.ValueString())} + if cDataKeys == cStateKeys { + cStateIndex = jj + break } } - } - } - return types.Int64Null() -} - -func (data *ApplicationAwareRouting) getMatchSourceDataPrefixListVersion(ctx context.Context, name string, id int64) types.Int64 { - for _, item := range data.Sequences { - if item.Name.ValueString() == name && item.Id.ValueInt64() == id { - for _, cItem := range item.MatchEntries { - if cItem.Type.ValueString() == "sourceDataPrefixList" { - return cItem.SourceDataPrefixListVersion - } + if cStateIndex >= -1 { + data.Sequences[i].MatchEntries[ii].ApplicationListVersion = state.Sequences[stateIndex].MatchEntries[cStateIndex].ApplicationListVersion + } else { + data.Sequences[i].MatchEntries[ii].ApplicationListVersion = types.Int64Null() } - } - } - return types.Int64Null() -} - -func (data *ApplicationAwareRouting) getMatchDestinationDataPrefixListVersion(ctx context.Context, name string, id int64) types.Int64 { - for _, item := range data.Sequences { - if item.Name.ValueString() == name && item.Id.ValueInt64() == id { - for _, cItem := range item.MatchEntries { - if cItem.Type.ValueString() == "destinationDataPrefixList" { - return cItem.DestinationDataPrefixListVersion - } + if cStateIndex >= -1 { + data.Sequences[i].MatchEntries[ii].DnsApplicationListVersion = state.Sequences[stateIndex].MatchEntries[cStateIndex].DnsApplicationListVersion + } else { + data.Sequences[i].MatchEntries[ii].DnsApplicationListVersion = types.Int64Null() } - } - } - return types.Int64Null() -} - -func (data *ApplicationAwareRouting) getActionSlaClassListVersion(ctx context.Context, name string, id int64) types.Int64 { - for _, item := range data.Sequences { - if item.Name.ValueString() == name && item.Id.ValueInt64() == id { - for _, cItem := range item.ActionEntries { - if cItem.Type.ValueString() == "slaClass" { - for _, ccItem := range cItem.CloudSlaParameters { - if ccItem.Type.ValueString() == "name" { - return ccItem.SlaClassListVersion - } - } - } + if cStateIndex >= -1 { + data.Sequences[i].MatchEntries[ii].SourceDataPrefixListVersion = state.Sequences[stateIndex].MatchEntries[cStateIndex].SourceDataPrefixListVersion + } else { + data.Sequences[i].MatchEntries[ii].SourceDataPrefixListVersion = types.Int64Null() } - } - } - return types.Int64Null() -} - -func (data *ApplicationAwareRouting) getActionPreferredColorGroupListVersion(ctx context.Context, name string, id int64) types.Int64 { - for _, item := range data.Sequences { - if item.Name.ValueString() == name && item.Id.ValueInt64() == id { - for _, cItem := range item.ActionEntries { - if cItem.Type.ValueString() == "slaClass" { - for _, ccItem := range cItem.CloudSlaParameters { - if ccItem.Type.ValueString() == "preferredColorGroup" { - return ccItem.PreferredColorGroupListVersion - } - } - } + if cStateIndex >= -1 { + data.Sequences[i].MatchEntries[ii].DestinationDataPrefixListVersion = state.Sequences[stateIndex].MatchEntries[cStateIndex].DestinationDataPrefixListVersion + } else { + data.Sequences[i].MatchEntries[ii].DestinationDataPrefixListVersion = types.Int64Null() } } - } - return types.Int64Null() -} - -func (data *ApplicationAwareRouting) updateVersions(ctx context.Context, state ApplicationAwareRouting) { - for s := range data.Sequences { - id := data.Sequences[s].Id.ValueInt64() - name := data.Sequences[s].Name.ValueString() - for m := range data.Sequences[s].MatchEntries { - t := data.Sequences[s].MatchEntries[m].Type.ValueString() - if t == "appList" { - data.Sequences[s].MatchEntries[m].ApplicationListVersion = state.getMatchApplicationListVersion(ctx, name, id) - } else if t == "dnsAppList" { - data.Sequences[s].MatchEntries[m].DnsApplicationListVersion = state.getMatchDnsApplicationListVersion(ctx, name, id) - } else if t == "sourceDataPrefixList" { - data.Sequences[s].MatchEntries[m].SourceDataPrefixListVersion = state.getMatchSourceDataPrefixListVersion(ctx, name, id) - } else if t == "destinationDataPrefixList" { - data.Sequences[s].MatchEntries[m].DestinationDataPrefixListVersion = state.getMatchDestinationDataPrefixListVersion(ctx, name, id) + for ii := range data.Sequences[i].ActionEntries { + cDataKeys := [...]string{fmt.Sprintf("%v", data.Sequences[i].ActionEntries[ii].Type.ValueString())} + cStateIndex := -1 + for jj := range state.Sequences[stateIndex].ActionEntries { + cStateKeys := [...]string{fmt.Sprintf("%v", state.Sequences[stateIndex].ActionEntries[jj].Type.ValueString())} + if cDataKeys == cStateKeys { + cStateIndex = jj + break + } } - } - for a := range data.Sequences[s].ActionEntries { - t := data.Sequences[s].ActionEntries[a].Type.ValueString() - if t == "slaClass" { - for s := range data.Sequences[s].ActionEntries[a].CloudSlaParameters { - st := data.Sequences[s].ActionEntries[a].CloudSlaParameters[s].Type.ValueString() - if st == "name" { - data.Sequences[s].ActionEntries[a].CloudSlaParameters[s].SlaClassListVersion = state.getActionSlaClassListVersion(ctx, name, id) - } else if st == "preferredColorGroup" && data.Sequences[s].ActionEntries[a].CloudSlaParameters[s].PreferredColorGroupList.ValueString() != "" { - data.Sequences[s].ActionEntries[a].CloudSlaParameters[s].PreferredColorGroupListVersion = state.getActionPreferredColorGroupListVersion(ctx, name, id) + for iii := range data.Sequences[i].ActionEntries[ii].SlaClassParameters { + ccDataKeys := [...]string{fmt.Sprintf("%v", data.Sequences[i].ActionEntries[ii].SlaClassParameters[iii].Type.ValueString())} + ccStateIndex := -1 + for jjj := range state.Sequences[stateIndex].ActionEntries[cStateIndex].SlaClassParameters { + ccStateKeys := [...]string{fmt.Sprintf("%v", state.Sequences[stateIndex].ActionEntries[cStateIndex].SlaClassParameters[jjj].Type.ValueString())} + if ccDataKeys == ccStateKeys { + ccStateIndex = jjj + break } } + if ccStateIndex >= -1 { + data.Sequences[i].ActionEntries[ii].SlaClassParameters[iii].SlaClassListVersion = state.Sequences[stateIndex].ActionEntries[cStateIndex].SlaClassParameters[ccStateIndex].SlaClassListVersion + } else { + data.Sequences[i].ActionEntries[ii].SlaClassParameters[iii].SlaClassListVersion = types.Int64Null() + } + if ccStateIndex >= -1 { + data.Sequences[i].ActionEntries[ii].SlaClassParameters[iii].PreferredColorGroupListVersion = state.Sequences[stateIndex].ActionEntries[cStateIndex].SlaClassParameters[ccStateIndex].PreferredColorGroupListVersion + } else { + data.Sequences[i].ActionEntries[ii].SlaClassParameters[iii].PreferredColorGroupListVersion = types.Int64Null() + } } } } diff --git a/internal/provider/provider.go b/internal/provider/provider.go index f02f0dcf..f47dd1b6 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -282,7 +282,6 @@ func (p *SdwanProvider) Resources(ctx context.Context) []func() resource.Resourc NewTLOCListPolicyObjectResource, NewVPNListPolicyObjectResource, NewACLPolicyDefinitionResource, - NewApplicationAwareRoutingPolicyDefinitionResource, NewCustomControlTopologyPolicyDefinitionResource, NewDeviceACLPolicyDefinitionResource, NewHubAndSpokeTopologyPolicyDefinitionResource, @@ -290,6 +289,7 @@ func (p *SdwanProvider) Resources(ctx context.Context) []func() resource.Resourc NewQoSMapPolicyDefinitionResource, NewRewriteRulePolicyDefinitionResource, NewRoutePolicyDefinitionResource, + NewApplicationAwareRoutingPolicyDefinitionResource, NewCflowdPolicyDefinitionResource, NewTrafficDataPolicyDefinitionResource, NewVPNMembershipPolicyDefinitionResource, @@ -343,7 +343,6 @@ func (p *SdwanProvider) DataSources(ctx context.Context) []func() datasource.Dat NewTLOCListPolicyObjectDataSource, NewVPNListPolicyObjectDataSource, NewACLPolicyDefinitionDataSource, - NewApplicationAwareRoutingPolicyDefinitionDataSource, NewCustomControlTopologyPolicyDefinitionDataSource, NewDeviceACLPolicyDefinitionDataSource, NewHubAndSpokeTopologyPolicyDefinitionDataSource, @@ -351,6 +350,7 @@ func (p *SdwanProvider) DataSources(ctx context.Context) []func() datasource.Dat NewQoSMapPolicyDefinitionDataSource, NewRewriteRulePolicyDefinitionDataSource, NewRoutePolicyDefinitionDataSource, + NewApplicationAwareRoutingPolicyDefinitionDataSource, NewCflowdPolicyDefinitionDataSource, NewTrafficDataPolicyDefinitionDataSource, NewVPNMembershipPolicyDefinitionDataSource, diff --git a/internal/provider/resource_sdwan_application_aware_routing_policy_definition.go b/internal/provider/resource_sdwan_application_aware_routing_policy_definition.go index 42e8d5ee..9f4bc0da 100644 --- a/internal/provider/resource_sdwan_application_aware_routing_policy_definition.go +++ b/internal/provider/resource_sdwan_application_aware_routing_policy_definition.go @@ -59,33 +59,26 @@ func (r *ApplicationAwareRoutingPolicyDefinitionResource) Metadata(ctx context.C func (r *ApplicationAwareRoutingPolicyDefinitionResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { resp.Schema = schema.Schema{ // This description is used by the documentation generator and the language server. - MarkdownDescription: helpers.NewAttributeDescription("This resource can manage a Application Aware Routing policy definition.").String, + MarkdownDescription: helpers.NewAttributeDescription("This resource can manage a Application Aware Routing Policy Definition .").String, Attributes: map[string]schema.Attribute{ "id": schema.StringAttribute{ - MarkdownDescription: "The id of the policy definition", + MarkdownDescription: "The id of the object", Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), }, }, "version": schema.Int64Attribute{ - MarkdownDescription: "The version of the policy definition", + MarkdownDescription: "The version of the object", Computed: true, }, - "type": schema.StringAttribute{ - MarkdownDescription: "The policy defintion type", - Computed: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, - }, "name": schema.StringAttribute{ - MarkdownDescription: "The name of the policy definition", + MarkdownDescription: helpers.NewAttributeDescription("The name of the policy definition").String, Required: true, }, "description": schema.StringAttribute{ - MarkdownDescription: "The description of the policy definition", + MarkdownDescription: helpers.NewAttributeDescription("The description of the policy definition").String, Required: true, }, "sequences": schema.ListNestedAttribute{ @@ -239,27 +232,21 @@ func (r *ApplicationAwareRoutingPolicyDefinitionResource) Schema(ctx context.Con MarkdownDescription: helpers.NewAttributeDescription("Counter name").String, Optional: true, }, - "log": schema.StringAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Enable logging").AddStringEnumDescription("").String, + "log": schema.BoolAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Enable logging").String, Optional: true, - Validators: []validator.String{ - stringvalidator.OneOf(""), - }, }, - "cloud_sla": schema.StringAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Cloud SLA").AddStringEnumDescription("").String, + "cloud_sla": schema.BoolAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Cloud SLA").String, Optional: true, - Validators: []validator.String{ - stringvalidator.OneOf(""), - }, }, - "cloud_sla_parameters": schema.ListNestedAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("List of cloud SLA parameters").String, + "sla_class_parameters": schema.ListNestedAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("List of SLA class parameters").String, Optional: true, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{ "type": schema.StringAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("Type of cloud SLA parameter").AddStringEnumDescription("name", "preferredColor", "preferredColorGroup").String, + MarkdownDescription: helpers.NewAttributeDescription("Type of SLA class parameter").AddStringEnumDescription("name", "preferredColor", "preferredColorGroup").String, Required: true, Validators: []validator.String{ stringvalidator.OneOf("name", "preferredColor", "preferredColorGroup"), @@ -308,7 +295,7 @@ func (r *ApplicationAwareRoutingPolicyDefinitionResource) Configure(_ context.Co } func (r *ApplicationAwareRoutingPolicyDefinitionResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var plan ApplicationAwareRouting + var plan ApplicationAwareRoutingPolicyDefinition // Read plan diags := req.Plan.Get(ctx, &plan) @@ -322,7 +309,7 @@ func (r *ApplicationAwareRoutingPolicyDefinitionResource) Create(ctx context.Con // Create object body := plan.toBody(ctx) - res, err := r.client.Post("/template/policy/definition/approute", body) + res, err := r.client.Post("/template/policy/definition/approute/", body) if err != nil { resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (POST), got error: %s, %s", err, res.String())) return @@ -330,7 +317,6 @@ func (r *ApplicationAwareRoutingPolicyDefinitionResource) Create(ctx context.Con plan.Id = types.StringValue(res.Get("definitionId").String()) plan.Version = types.Int64Value(0) - plan.Type = types.StringValue(plan.getType()) tflog.Debug(ctx, fmt.Sprintf("%s: Create finished successfully", plan.Name.ValueString())) @@ -339,7 +325,7 @@ func (r *ApplicationAwareRoutingPolicyDefinitionResource) Create(ctx context.Con } func (r *ApplicationAwareRoutingPolicyDefinitionResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var state, oldState ApplicationAwareRouting + var state ApplicationAwareRoutingPolicyDefinition // Read state diags := req.State.Get(ctx, &state) @@ -347,11 +333,6 @@ func (r *ApplicationAwareRoutingPolicyDefinitionResource) Read(ctx context.Conte if resp.Diagnostics.HasError() { return } - diags = req.State.Get(ctx, &oldState) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", state.Name.String())) @@ -365,7 +346,6 @@ func (r *ApplicationAwareRoutingPolicyDefinitionResource) Read(ctx context.Conte } state.fromBody(ctx, res) - state.updateVersions(ctx, oldState) tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", state.Name.ValueString())) @@ -374,7 +354,7 @@ func (r *ApplicationAwareRoutingPolicyDefinitionResource) Read(ctx context.Conte } func (r *ApplicationAwareRoutingPolicyDefinitionResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan, state ApplicationAwareRouting + var plan, state ApplicationAwareRoutingPolicyDefinition // Read plan diags := req.Plan.Get(ctx, &plan) @@ -407,7 +387,6 @@ func (r *ApplicationAwareRoutingPolicyDefinitionResource) Update(ctx context.Con } else { tflog.Debug(ctx, fmt.Sprintf("%s: No changes detected", plan.Name.ValueString())) } - plan.Version = types.Int64Value(state.Version.ValueInt64() + 1) tflog.Debug(ctx, fmt.Sprintf("%s: Update finished successfully", plan.Name.ValueString())) @@ -417,7 +396,7 @@ func (r *ApplicationAwareRoutingPolicyDefinitionResource) Update(ctx context.Con } func (r *ApplicationAwareRoutingPolicyDefinitionResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ApplicationAwareRouting + var state ApplicationAwareRoutingPolicyDefinition // Read state diags := req.State.Get(ctx, &state) diff --git a/internal/provider/resource_sdwan_application_aware_routing_policy_definition_test.go b/internal/provider/resource_sdwan_application_aware_routing_policy_definition_test.go index 039da70c..b633207a 100644 --- a/internal/provider/resource_sdwan_application_aware_routing_policy_definition_test.go +++ b/internal/provider/resource_sdwan_application_aware_routing_policy_definition_test.go @@ -33,6 +33,8 @@ func TestAccSdwanApplicationAwareRoutingPolicyDefinition(t *testing.T) { { Config: testAccSdwanApplicationAwareRoutingPolicyDefinitionConfig_all(), Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("sdwan_application_aware_routing_policy_definition.test", "name", "Example"), + resource.TestCheckResourceAttr("sdwan_application_aware_routing_policy_definition.test", "description", "My description"), resource.TestCheckResourceAttr("sdwan_application_aware_routing_policy_definition.test", "sequences.0.id", "1"), resource.TestCheckResourceAttr("sdwan_application_aware_routing_policy_definition.test", "sequences.0.name", "Region1"), resource.TestCheckResourceAttr("sdwan_application_aware_routing_policy_definition.test", "sequences.0.ip_type", "ipv4"), @@ -49,8 +51,8 @@ func TestAccSdwanApplicationAwareRoutingPolicyDefinition(t *testing.T) { func testAccSdwanApplicationAwareRoutingPolicyDefinitionConfig_all() string { return ` resource "sdwan_application_aware_routing_policy_definition" "test" { - name = "TF_TEST_ALL" - description = "Terraform integration test" + name = "Example" + description = "My description" sequences = [{ id = 1 name = "Region1"