diff --git a/docs/data-sources/device_acl_policy_definition.md b/docs/data-sources/device_acl_policy_definition.md
index 3968478a..6d81a2e7 100644
--- a/docs/data-sources/device_acl_policy_definition.md
+++ b/docs/data-sources/device_acl_policy_definition.md
@@ -3,12 +3,12 @@
page_title: "sdwan_device_acl_policy_definition Data Source - terraform-provider-sdwan"
subcategory: "Localized Policies"
description: |-
- This data source can read the Device ACL policy definition.
+ This data source can read the Device ACL Policy Definition .
---
# sdwan_device_acl_policy_definition (Data Source)
-This data source can read the Device ACL policy definition.
+This data source can read the Device ACL Policy Definition .
## Example Usage
@@ -23,7 +23,7 @@ data "sdwan_device_acl_policy_definition" "example" {
### Required
-- `id` (String) The id of the policy definition
+- `id` (String) The id of the object
### Read-Only
@@ -31,8 +31,7 @@ data "sdwan_device_acl_policy_definition" "example" {
- `description` (String) The description of the policy definition
- `name` (String) The name of the policy definition
- `sequences` (Attributes List) List of ACL 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`
diff --git a/docs/resources/device_acl_policy_definition.md b/docs/resources/device_acl_policy_definition.md
index 449ca3c4..e4b9b77a 100644
--- a/docs/resources/device_acl_policy_definition.md
+++ b/docs/resources/device_acl_policy_definition.md
@@ -3,12 +3,12 @@
page_title: "sdwan_device_acl_policy_definition Resource - terraform-provider-sdwan"
subcategory: "Localized Policies"
description: |-
- This resource can manage a Device ACL policy definition.
+ This resource can manage a Device ACL Policy Definition .
---
# sdwan_device_acl_policy_definition (Resource)
-This resource can manage a Device ACL policy definition.
+This resource can manage a Device ACL Policy Definition .
## Example Usage
@@ -56,9 +56,8 @@ resource "sdwan_device_acl_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`
@@ -67,6 +66,7 @@ Required:
- `id` (Number) Sequence ID
- Range: `1`-`65534`
+- `name` (String) Sequence name
Optional:
@@ -76,7 +76,6 @@ Optional:
- `ip_type` (String) IP version, either `ipv4` or `ipv6`
- Choices: `ipv4`, `ipv6`
- `match_entries` (Attributes List) List of match entries (see [below for nested schema](#nestedatt--sequences--match_entries))
-- `name` (String) Sequence name
### Nested Schema for `sequences.action_entries`
@@ -104,7 +103,7 @@ Optional:
- `destination_data_prefix_list_id` (String) Destination data prefix list ID
- `destination_data_prefix_list_version` (Number) Destination data prefix list version
- `destination_ip` (String) Destination IP prefix
-- `destination_port` (Number) Destination port
+- `destination_port` (Number) Destination port, only `22` and `161` supported
- Range: `0`-`65535`
- `source_data_prefix_list_id` (String) Source data prefix list ID
- `source_data_prefix_list_version` (Number) Source data prefix list version
diff --git a/gen/definitions/policy_definitions/device_acl.yaml b/gen/definitions/generic/device_acl_policy_definition.yaml
similarity index 75%
rename from gen/definitions/policy_definitions/device_acl.yaml
rename to gen/definitions/generic/device_acl_policy_definition.yaml
index 2805952b..3820710f 100644
--- a/gen/definitions/policy_definitions/device_acl.yaml
+++ b/gen/definitions/generic/device_acl_policy_definition.yaml
@@ -1,9 +1,24 @@
---
-name: Device ACL
-type: deviceAccessPolicy
+name: Device ACL Policy Definition
+rest_endpoint: /template/policy/definition/deviceaccesspolicy/
+has_version: true
+id_attribute: definitionId
doc_category: Localized Policies
-skip_templates: [model.go, resource.go]
attributes:
+ - model_name: type
+ value: deviceAccessPolicy
+ - 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: type
tf_name: default_action
data_path: [defaultAction]
@@ -19,6 +34,7 @@ attributes:
- model_name: sequenceId
tf_name: id
type: Int64
+ id: true
mandatory: true
description: Sequence ID
min_int: 1
@@ -33,6 +49,8 @@ attributes:
- model_name: sequenceName
tf_name: name
type: String
+ id: true
+ mandatory: true
description: Sequence name
example: Sequence 10
- model_name: sequenceType
@@ -52,6 +70,7 @@ attributes:
- model_name: field
tf_name: type
type: String
+ id: true
mandatory: true
enum_values:
[
@@ -66,18 +85,27 @@ attributes:
example: destinationPort
- model_name: value
tf_name: source_ip
+ conditional_attribute:
+ name: type
+ value: sourceIp
type: String
description: Source IP prefix
exclude_test: true
example: 10.0.0.0/8
- model_name: value
tf_name: destination_ip
+ conditional_attribute:
+ name: type
+ value: destinationIp
type: String
description: Destination IP prefix
exclude_test: true
example: 192.168.0.0/16
- model_name: value
tf_name: source_port
+ conditional_attribute:
+ name: type
+ value: sourcePort
type: Int64
model_type_string: true
description: Source port
@@ -87,6 +115,9 @@ attributes:
example: 8000
- model_name: value
tf_name: destination_port
+ conditional_attribute:
+ name: type
+ value: destinationPort
type: Int64
model_type_string: true
description: Destination port, only `22` and `161` supported
@@ -95,24 +126,30 @@ attributes:
example: 22
- model_name: ref
tf_name: source_data_prefix_list_id
+ conditional_attribute:
+ name: type
+ value: sourceDataPrefixList
type: String
description: Source data prefix list ID
exclude_test: true
example: 2081c2f4-3f9f-4fee-8078-dcc8904e368d
- 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: ref
tf_name: destination_data_prefix_list_id
+ conditional_attribute:
+ name: type
+ value: destinationDataPrefixList
type: String
description: Destination data prefix list ID
exclude_test: true
example: 2081c2f4-3f9f-4fee-8078-dcc8904e368d
- 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: actions
@@ -123,12 +160,16 @@ attributes:
- model_name: type
tf_name: type
type: String
+ id: true
mandatory: true
enum_values: [count]
description: Type of action entry
example: count
- model_name: parameter
tf_name: counter_name
+ conditional_attribute:
+ name: type
+ value: count
type: String
description: Counter name
example: count1
diff --git a/internal/provider/data_source_sdwan_device_acl_policy_definition.go b/internal/provider/data_source_sdwan_device_acl_policy_definition.go
index 0977d87b..3e4d7067 100644
--- a/internal/provider/data_source_sdwan_device_acl_policy_definition.go
+++ b/internal/provider/data_source_sdwan_device_acl_policy_definition.go
@@ -50,19 +50,15 @@ func (d *DeviceACLPolicyDefinitionDataSource) Metadata(_ context.Context, req da
func (d *DeviceACLPolicyDefinitionDataSource) 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 Device ACL policy definition.",
+ MarkdownDescription: "This data source can read the Device ACL 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{
@@ -174,7 +170,7 @@ func (d *DeviceACLPolicyDefinitionDataSource) Configure(_ context.Context, req d
}
func (d *DeviceACLPolicyDefinitionDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
- var config DeviceACL
+ var config DeviceACLPolicyDefinition
// Read config
diags := req.Config.Get(ctx, &config)
diff --git a/internal/provider/data_source_sdwan_device_acl_policy_definition_test.go b/internal/provider/data_source_sdwan_device_acl_policy_definition_test.go
index c4fc4460..4633a433 100644
--- a/internal/provider/data_source_sdwan_device_acl_policy_definition_test.go
+++ b/internal/provider/data_source_sdwan_device_acl_policy_definition_test.go
@@ -33,6 +33,8 @@ func TestAccDataSourceSdwanDeviceACLPolicyDefinition(t *testing.T) {
{
Config: testAccDataSourceSdwanDeviceACLPolicyDefinitionConfig,
Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("data.sdwan_device_acl_policy_definition.test", "name", "Example"),
+ resource.TestCheckResourceAttr("data.sdwan_device_acl_policy_definition.test", "description", "My description"),
resource.TestCheckResourceAttr("data.sdwan_device_acl_policy_definition.test", "default_action", "drop"),
resource.TestCheckResourceAttr("data.sdwan_device_acl_policy_definition.test", "sequences.0.id", "10"),
resource.TestCheckResourceAttr("data.sdwan_device_acl_policy_definition.test", "sequences.0.ip_type", "ipv4"),
@@ -51,8 +53,8 @@ func TestAccDataSourceSdwanDeviceACLPolicyDefinition(t *testing.T) {
const testAccDataSourceSdwanDeviceACLPolicyDefinitionConfig = `
resource "sdwan_device_acl_policy_definition" "test" {
- name = "TF_TEST_MIN"
- description = "Terraform integration test"
+ name = "Example"
+ description = "My description"
default_action = "drop"
sequences = [{
id = 10
diff --git a/internal/provider/model_sdwan_device_acl_policy_definition.go b/internal/provider/model_sdwan_device_acl_policy_definition.go
index 685f0664..a5c459ba 100644
--- a/internal/provider/model_sdwan_device_acl_policy_definition.go
+++ b/internal/provider/model_sdwan_device_acl_policy_definition.go
@@ -28,26 +28,25 @@ import (
"github.com/tidwall/sjson"
)
-type DeviceACL 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"`
- DefaultAction types.String `tfsdk:"default_action"`
- Sequences []DeviceACLSequences `tfsdk:"sequences"`
+type DeviceACLPolicyDefinition struct {
+ Id types.String `tfsdk:"id"`
+ Version types.Int64 `tfsdk:"version"`
+ Name types.String `tfsdk:"name"`
+ Description types.String `tfsdk:"description"`
+ DefaultAction types.String `tfsdk:"default_action"`
+ Sequences []DeviceACLPolicyDefinitionSequences `tfsdk:"sequences"`
}
-type DeviceACLSequences struct {
- Id types.Int64 `tfsdk:"id"`
- IpType types.String `tfsdk:"ip_type"`
- Name types.String `tfsdk:"name"`
- BaseAction types.String `tfsdk:"base_action"`
- MatchEntries []DeviceACLSequencesMatchEntries `tfsdk:"match_entries"`
- ActionEntries []DeviceACLSequencesActionEntries `tfsdk:"action_entries"`
+type DeviceACLPolicyDefinitionSequences struct {
+ Id types.Int64 `tfsdk:"id"`
+ IpType types.String `tfsdk:"ip_type"`
+ Name types.String `tfsdk:"name"`
+ BaseAction types.String `tfsdk:"base_action"`
+ MatchEntries []DeviceACLPolicyDefinitionSequencesMatchEntries `tfsdk:"match_entries"`
+ ActionEntries []DeviceACLPolicyDefinitionSequencesActionEntries `tfsdk:"action_entries"`
}
-type DeviceACLSequencesMatchEntries struct {
+type DeviceACLPolicyDefinitionSequencesMatchEntries struct {
Type types.String `tfsdk:"type"`
SourceIp types.String `tfsdk:"source_ip"`
DestinationIp types.String `tfsdk:"destination_ip"`
@@ -58,25 +57,25 @@ type DeviceACLSequencesMatchEntries struct {
DestinationDataPrefixListId types.String `tfsdk:"destination_data_prefix_list_id"`
DestinationDataPrefixListVersion types.Int64 `tfsdk:"destination_data_prefix_list_version"`
}
-type DeviceACLSequencesActionEntries struct {
+type DeviceACLPolicyDefinitionSequencesActionEntries struct {
Type types.String `tfsdk:"type"`
CounterName types.String `tfsdk:"counter_name"`
}
-func (data DeviceACL) getType() string {
- return "deviceAccessPolicy"
-}
-
-func (data DeviceACL) toBody(ctx context.Context) string {
- body, _ := sjson.Set("", "name", data.Name.ValueString())
- body, _ = sjson.Set(body, "description", data.Description.ValueString())
+func (data DeviceACLPolicyDefinition) toBody(ctx context.Context) string {
+ body := ""
body, _ = sjson.Set(body, "type", "deviceAccessPolicy")
- 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 !data.DefaultAction.IsNull() {
- body, _ = sjson.Set(body, path+"defaultAction.type", data.DefaultAction.ValueString())
+ body, _ = sjson.Set(body, "defaultAction.type", data.DefaultAction.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() {
@@ -99,22 +98,22 @@ func (data DeviceACL) toBody(ctx context.Context) string {
if !childItem.Type.IsNull() {
itemChildBody, _ = sjson.Set(itemChildBody, "field", childItem.Type.ValueString())
}
- if !childItem.SourceIp.IsNull() {
+ if !childItem.SourceIp.IsNull() && childItem.Type.ValueString() == "sourceIp" {
itemChildBody, _ = sjson.Set(itemChildBody, "value", childItem.SourceIp.ValueString())
}
- if !childItem.DestinationIp.IsNull() {
+ if !childItem.DestinationIp.IsNull() && childItem.Type.ValueString() == "destinationIp" {
itemChildBody, _ = sjson.Set(itemChildBody, "value", childItem.DestinationIp.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.DestinationPort.IsNull() {
+ if !childItem.DestinationPort.IsNull() && childItem.Type.ValueString() == "destinationPort" {
itemChildBody, _ = sjson.Set(itemChildBody, "value", fmt.Sprint(childItem.DestinationPort.ValueInt64()))
}
- if !childItem.SourceDataPrefixListId.IsNull() {
+ if !childItem.SourceDataPrefixListId.IsNull() && childItem.Type.ValueString() == "sourceDataPrefixList" {
itemChildBody, _ = sjson.Set(itemChildBody, "ref", childItem.SourceDataPrefixListId.ValueString())
}
- if !childItem.DestinationDataPrefixListId.IsNull() {
+ if !childItem.DestinationDataPrefixListId.IsNull() && childItem.Type.ValueString() == "destinationDataPrefixList" {
itemChildBody, _ = sjson.Set(itemChildBody, "ref", childItem.DestinationDataPrefixListId.ValueString())
}
itemBody, _ = sjson.SetRaw(itemBody, "match.entries.-1", itemChildBody)
@@ -127,19 +126,19 @@ func (data DeviceACL) toBody(ctx context.Context) string {
if !childItem.Type.IsNull() {
itemChildBody, _ = sjson.Set(itemChildBody, "type", childItem.Type.ValueString())
}
- if !childItem.CounterName.IsNull() {
+ if !childItem.CounterName.IsNull() && childItem.Type.ValueString() == "count" {
itemChildBody, _ = sjson.Set(itemChildBody, "parameter", childItem.CounterName.ValueString())
}
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 *DeviceACL) fromBody(ctx context.Context, res gjson.Result) {
+func (data *DeviceACLPolicyDefinition) fromBody(ctx context.Context, res gjson.Result) {
if value := res.Get("name"); value.Exists() {
data.Name = types.StringValue(value.String())
} else {
@@ -150,21 +149,15 @@ func (data *DeviceACL) fromBody(ctx context.Context, res gjson.Result) {
} 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 + "defaultAction.type"); value.Exists() {
+ if value := res.Get("defaultAction.type"); value.Exists() {
data.DefaultAction = types.StringValue(value.String())
} else {
data.DefaultAction = types.StringNull()
}
- if value := res.Get(path + "sequences"); value.Exists() {
- data.Sequences = make([]DeviceACLSequences, 0)
+ if value := res.Get("sequences"); value.Exists() {
+ data.Sequences = make([]DeviceACLPolicyDefinitionSequences, 0)
value.ForEach(func(k, v gjson.Result) bool {
- item := DeviceACLSequences{}
+ item := DeviceACLPolicyDefinitionSequences{}
if cValue := v.Get("sequenceId"); cValue.Exists() {
item.Id = types.Int64Value(cValue.Int())
} else {
@@ -186,40 +179,40 @@ func (data *DeviceACL) fromBody(ctx context.Context, res gjson.Result) {
item.BaseAction = types.StringNull()
}
if cValue := v.Get("match.entries"); cValue.Exists() {
- item.MatchEntries = make([]DeviceACLSequencesMatchEntries, 0)
+ item.MatchEntries = make([]DeviceACLPolicyDefinitionSequencesMatchEntries, 0)
cValue.ForEach(func(ck, cv gjson.Result) bool {
- cItem := DeviceACLSequencesMatchEntries{}
+ cItem := DeviceACLPolicyDefinitionSequencesMatchEntries{}
if ccValue := cv.Get("field"); ccValue.Exists() {
cItem.Type = types.StringValue(ccValue.String())
} else {
cItem.Type = 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() == "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() == "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("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("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("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()
@@ -229,15 +222,15 @@ func (data *DeviceACL) fromBody(ctx context.Context, res gjson.Result) {
})
}
if cValue := v.Get("actions"); cValue.Exists() {
- item.ActionEntries = make([]DeviceACLSequencesActionEntries, 0)
+ item.ActionEntries = make([]DeviceACLPolicyDefinitionSequencesActionEntries, 0)
cValue.ForEach(func(ck, cv gjson.Result) bool {
- cItem := DeviceACLSequencesActionEntries{}
+ cItem := DeviceACLPolicyDefinitionSequencesActionEntries{}
if ccValue := cv.Get("type"); ccValue.Exists() {
cItem.Type = types.StringValue(ccValue.String())
} else {
cItem.Type = types.StringNull()
}
- if ccValue := cv.Get("parameter"); ccValue.Exists() {
+ if ccValue := cv.Get("parameter"); ccValue.Exists() && cItem.Type.ValueString() == "count" {
cItem.CounterName = types.StringValue(ccValue.String())
} else {
cItem.CounterName = types.StringNull()
@@ -250,9 +243,12 @@ func (data *DeviceACL) fromBody(ctx context.Context, res gjson.Result) {
return true
})
}
+
+ data.updateVersions(ctx)
+
}
-func (data *DeviceACL) hasChanges(ctx context.Context, state *DeviceACL) bool {
+func (data *DeviceACLPolicyDefinition) hasChanges(ctx context.Context, state *DeviceACLPolicyDefinition) bool {
hasChanges := false
if !data.Name.Equal(state.Name) {
hasChanges = true
@@ -323,42 +319,37 @@ func (data *DeviceACL) hasChanges(ctx context.Context, state *DeviceACL) bool {
return hasChanges
}
-func (data *DeviceACL) 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
- }
+func (data *DeviceACLPolicyDefinition) 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 *DeviceACL) 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
+ 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 *DeviceACL) updateVersions(ctx context.Context, state DeviceACL) {
- 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 == "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)
+ if cStateIndex >= -1 {
+ data.Sequences[i].MatchEntries[ii].SourceDataPrefixListVersion = state.Sequences[stateIndex].MatchEntries[cStateIndex].SourceDataPrefixListVersion
+ } else {
+ data.Sequences[i].MatchEntries[ii].SourceDataPrefixListVersion = types.Int64Null()
+ }
+ if cStateIndex >= -1 {
+ data.Sequences[i].MatchEntries[ii].DestinationDataPrefixListVersion = state.Sequences[stateIndex].MatchEntries[cStateIndex].DestinationDataPrefixListVersion
+ } else {
+ data.Sequences[i].MatchEntries[ii].DestinationDataPrefixListVersion = types.Int64Null()
}
}
}
diff --git a/internal/provider/provider.go b/internal/provider/provider.go
index 0270d820..02aab563 100644
--- a/internal/provider/provider.go
+++ b/internal/provider/provider.go
@@ -281,7 +281,6 @@ func (p *SdwanProvider) Resources(ctx context.Context) []func() resource.Resourc
NewStandardCommunityListPolicyObjectResource,
NewTLOCListPolicyObjectResource,
NewVPNListPolicyObjectResource,
- NewDeviceACLPolicyDefinitionResource,
NewQoSMapPolicyDefinitionResource,
NewRewriteRulePolicyDefinitionResource,
NewRoutePolicyDefinitionResource,
@@ -289,6 +288,7 @@ func (p *SdwanProvider) Resources(ctx context.Context) []func() resource.Resourc
NewApplicationAwareRoutingPolicyDefinitionResource,
NewCflowdPolicyDefinitionResource,
NewCustomControlTopologyPolicyDefinitionResource,
+ NewDeviceACLPolicyDefinitionResource,
NewHubAndSpokeTopologyPolicyDefinitionResource,
NewMeshTopologyPolicyDefinitionResource,
NewTrafficDataPolicyDefinitionResource,
@@ -342,7 +342,6 @@ func (p *SdwanProvider) DataSources(ctx context.Context) []func() datasource.Dat
NewStandardCommunityListPolicyObjectDataSource,
NewTLOCListPolicyObjectDataSource,
NewVPNListPolicyObjectDataSource,
- NewDeviceACLPolicyDefinitionDataSource,
NewQoSMapPolicyDefinitionDataSource,
NewRewriteRulePolicyDefinitionDataSource,
NewRoutePolicyDefinitionDataSource,
@@ -350,6 +349,7 @@ func (p *SdwanProvider) DataSources(ctx context.Context) []func() datasource.Dat
NewApplicationAwareRoutingPolicyDefinitionDataSource,
NewCflowdPolicyDefinitionDataSource,
NewCustomControlTopologyPolicyDefinitionDataSource,
+ NewDeviceACLPolicyDefinitionDataSource,
NewHubAndSpokeTopologyPolicyDefinitionDataSource,
NewMeshTopologyPolicyDefinitionDataSource,
NewTrafficDataPolicyDefinitionDataSource,
diff --git a/internal/provider/resource_sdwan_device_acl_policy_definition.go b/internal/provider/resource_sdwan_device_acl_policy_definition.go
index d7598914..9fc1a108 100644
--- a/internal/provider/resource_sdwan_device_acl_policy_definition.go
+++ b/internal/provider/resource_sdwan_device_acl_policy_definition.go
@@ -59,33 +59,26 @@ func (r *DeviceACLPolicyDefinitionResource) Metadata(ctx context.Context, req re
func (r *DeviceACLPolicyDefinitionResource) 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 Device ACL policy definition.").String,
+ MarkdownDescription: helpers.NewAttributeDescription("This resource can manage a Device ACL 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,
},
"default_action": schema.StringAttribute{
@@ -116,7 +109,7 @@ func (r *DeviceACLPolicyDefinitionResource) Schema(ctx context.Context, req reso
},
"name": schema.StringAttribute{
MarkdownDescription: helpers.NewAttributeDescription("Sequence name").String,
- Optional: true,
+ Required: true,
},
"base_action": schema.StringAttribute{
MarkdownDescription: helpers.NewAttributeDescription("Base action, either `accept` or `drop`").AddStringEnumDescription("accept", "drop").String,
@@ -153,7 +146,7 @@ func (r *DeviceACLPolicyDefinitionResource) Schema(ctx context.Context, req reso
},
},
"destination_port": schema.Int64Attribute{
- MarkdownDescription: helpers.NewAttributeDescription("Destination port").AddIntegerRangeDescription(0, 65535).String,
+ MarkdownDescription: helpers.NewAttributeDescription("Destination port, only `22` and `161` supported").AddIntegerRangeDescription(0, 65535).String,
Optional: true,
Validators: []validator.Int64{
int64validator.Between(0, 65535),
@@ -214,7 +207,7 @@ func (r *DeviceACLPolicyDefinitionResource) Configure(_ context.Context, req res
}
func (r *DeviceACLPolicyDefinitionResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
- var plan DeviceACL
+ var plan DeviceACLPolicyDefinition
// Read plan
diags := req.Plan.Get(ctx, &plan)
@@ -228,7 +221,7 @@ func (r *DeviceACLPolicyDefinitionResource) Create(ctx context.Context, req reso
// Create object
body := plan.toBody(ctx)
- res, err := r.client.Post("/template/policy/definition/deviceaccesspolicy", body)
+ res, err := r.client.Post("/template/policy/definition/deviceaccesspolicy/", body)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (POST), got error: %s, %s", err, res.String()))
return
@@ -236,7 +229,6 @@ func (r *DeviceACLPolicyDefinitionResource) Create(ctx context.Context, req reso
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()))
@@ -245,7 +237,7 @@ func (r *DeviceACLPolicyDefinitionResource) Create(ctx context.Context, req reso
}
func (r *DeviceACLPolicyDefinitionResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
- var state, oldState DeviceACL
+ var state DeviceACLPolicyDefinition
// Read state
diags := req.State.Get(ctx, &state)
@@ -253,11 +245,6 @@ func (r *DeviceACLPolicyDefinitionResource) Read(ctx context.Context, req resour
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()))
@@ -271,7 +258,6 @@ func (r *DeviceACLPolicyDefinitionResource) Read(ctx context.Context, req resour
}
state.fromBody(ctx, res)
- state.updateVersions(ctx, oldState)
tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", state.Name.ValueString()))
@@ -280,7 +266,7 @@ func (r *DeviceACLPolicyDefinitionResource) Read(ctx context.Context, req resour
}
func (r *DeviceACLPolicyDefinitionResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
- var plan, state DeviceACL
+ var plan, state DeviceACLPolicyDefinition
// Read plan
diags := req.Plan.Get(ctx, &plan)
@@ -313,7 +299,6 @@ func (r *DeviceACLPolicyDefinitionResource) Update(ctx context.Context, req reso
} 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()))
@@ -323,7 +308,7 @@ func (r *DeviceACLPolicyDefinitionResource) Update(ctx context.Context, req reso
}
func (r *DeviceACLPolicyDefinitionResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
- var state DeviceACL
+ var state DeviceACLPolicyDefinition
// Read state
diags := req.State.Get(ctx, &state)
diff --git a/internal/provider/resource_sdwan_device_acl_policy_definition_test.go b/internal/provider/resource_sdwan_device_acl_policy_definition_test.go
index c3c27438..9d547628 100644
--- a/internal/provider/resource_sdwan_device_acl_policy_definition_test.go
+++ b/internal/provider/resource_sdwan_device_acl_policy_definition_test.go
@@ -33,6 +33,8 @@ func TestAccSdwanDeviceACLPolicyDefinition(t *testing.T) {
{
Config: testAccSdwanDeviceACLPolicyDefinitionConfig_all(),
Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("sdwan_device_acl_policy_definition.test", "name", "Example"),
+ resource.TestCheckResourceAttr("sdwan_device_acl_policy_definition.test", "description", "My description"),
resource.TestCheckResourceAttr("sdwan_device_acl_policy_definition.test", "default_action", "drop"),
resource.TestCheckResourceAttr("sdwan_device_acl_policy_definition.test", "sequences.0.id", "10"),
resource.TestCheckResourceAttr("sdwan_device_acl_policy_definition.test", "sequences.0.ip_type", "ipv4"),
@@ -51,8 +53,8 @@ func TestAccSdwanDeviceACLPolicyDefinition(t *testing.T) {
func testAccSdwanDeviceACLPolicyDefinitionConfig_all() string {
return `
resource "sdwan_device_acl_policy_definition" "test" {
- name = "TF_TEST_ALL"
- description = "Terraform integration test"
+ name = "Example"
+ description = "My description"
default_action = "drop"
sequences = [{
id = 10