diff --git a/CHANGELOG.md b/CHANGELOG.md
index 07b10179..107be01c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,10 @@
- Add `iosxr_rd_set` resource and data source
- Add `contact` and `location` attributes to `iosxr_snmp_server` resource and data source
- Add `police_conform_action_transmit`, `police_conform_action_drop`, `police_exceed_action_transmit`, `police_exceed_action_drop`, `police_violate_action_transmit`, `police_violate_action_drop` attributes to `iosxr_policy_map_qos` resource and data source
+- Add `iosxr_bfd` resource and data source
+- Add `iosxr_flow_exporter_map` resource and data source
+
+
## 0.2.1
diff --git a/docs/data-sources/bfd.md b/docs/data-sources/bfd.md
new file mode 100644
index 00000000..b7ce37e8
--- /dev/null
+++ b/docs/data-sources/bfd.md
@@ -0,0 +1,75 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "iosxr_bfd Data Source - terraform-provider-iosxr"
+subcategory: "System"
+description: |-
+ This data source can read the BFD configuration.
+---
+
+# iosxr_bfd (Data Source)
+
+This data source can read the BFD configuration.
+
+## Example Usage
+
+```terraform
+data "iosxr_bfd" "example" {
+}
+```
+
+
+## Schema
+
+### Optional
+
+- `device` (String) A device name from the provider configuration.
+
+### Read-Only
+
+- `bundle_coexistence_bob_blb_inherit` (Boolean) Use inheritence mechanism
+- `bundle_coexistence_bob_blb_logical` (Boolean) Use BFD logical Bundle natively
+- `dampening_bundle_member_initial_wait` (Number) Initial delay before bringing up session
+- `dampening_bundle_member_l3_only_mode` (Boolean) Apply immediate dampening and only when failure is L3 specific
+- `dampening_bundle_member_maximum_wait` (Number) Maximum delay before bringing up session
+- `dampening_bundle_member_secondary_wait` (Number) Secondary delay before bringing up session
+- `dampening_disable` (Boolean) Disable BFD dampening
+- `dampening_extensions_down_monitoring` (Boolean) Enable DOWN state session monitoring extensions
+- `dampening_initial_wait` (Number) Initial delay before bringing up session
+- `dampening_maximum_wait` (Number) Maximum delay before bringing up session
+- `dampening_secondary_wait` (Number) Secondary delay before bringing up session
+- `dampening_threshold` (Number) Stability threshold to enable dampening
+- `echo_disable` (Boolean) Disable BFD echo mode
+- `echo_ipv4_bundle_per_member_minimum_interval_preferred_minimum_interval` (Number) The preferred minimum interval (in ms) for the BFD session
+- `echo_ipv4_source` (String) BFD echo source IP address
+- `echo_latency_detect_count` (Number) Count of consecutive bad latency packets to take session down
+- `echo_latency_detect_percentage` (Number) Percentage of detection time to consider as bad latency
+- `echo_startup_validate_force` (Boolean) Ignore remote 'Required Min Echo RX Interval' setting
+- `id` (String) The path of the retrieved object.
+- `interfaces` (Attributes List) Configure BFD on an interface (see [below for nested schema](#nestedatt--interfaces))
+- `ipv6_checksum_disable` (Boolean) Disable BFD checksum
+- `multihop_ttl_drop_threshold` (Number) TTL Drop Threshold
+- `multipath_locations` (Attributes List) Specify a location (see [below for nested schema](#nestedatt--multipath_locations))
+- `trap_singlehop_pre_mapped` (Boolean) Configure BFD trap pre-mapped
+
+
+### Nested Schema for `interfaces`
+
+Read-Only:
+
+- `disable` (Boolean) Disable BFD for this interface
+- `echo_disable` (Boolean) Disable BFD echo mode for this interface
+- `echo_ipv4_source` (String) BFD echo source IP address
+- `interface_name` (String) Configure BFD on an interface
+- `ipv6_checksum_disable` (Boolean) Disable BFD ipv6 checksum mode for this interface
+- `local_address` (String) Local address to be used by BFD for this interface
+- `multiplier` (Number) BFD multiplier for this interface
+- `rx_interval` (Number) BFD RX Interval for this interface in microseconds
+- `tx_interval` (Number) BFD TX Interval for this interface in microseconds
+
+
+
+### Nested Schema for `multipath_locations`
+
+Read-Only:
+
+- `location_name` (String) Specify a location
diff --git a/docs/data-sources/flow_exporter_map.md b/docs/data-sources/flow_exporter_map.md
new file mode 100644
index 00000000..255b9f1c
--- /dev/null
+++ b/docs/data-sources/flow_exporter_map.md
@@ -0,0 +1,53 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "iosxr_flow_exporter_map Data Source - terraform-provider-iosxr"
+subcategory: "Flow"
+description: |-
+ This data source can read the Flow Exporter Map configuration.
+---
+
+# iosxr_flow_exporter_map (Data Source)
+
+This data source can read the Flow Exporter Map configuration.
+
+## Example Usage
+
+```terraform
+data "iosxr_flow_exporter_map" "example" {
+}
+```
+
+
+## Schema
+
+### Optional
+
+- `device` (String) A device name from the provider configuration.
+
+### Read-Only
+
+- `exporter_maps` (Attributes List) Exporter map name - maximum 32 characters (see [below for nested schema](#nestedatt--exporter_maps))
+- `id` (String) The path of the retrieved object.
+
+
+### Nested Schema for `exporter_maps`
+
+Read-Only:
+
+- `destination_ipv4_address` (String) Destination IPv4 address
+- `destination_ipv6_address` (String) Destination IPv6 address
+- `destination_vrf` (String) Configure VRF to be used for reaching export destination
+- `dfbit_set` (Boolean) Set Export Packet Do Not Fragment Flag
+- `dscp` (Number) Specify DSCP value for ipv4 export packets or traffic-class for ipv6 export packets
+- `exporter_map_name` (String) Exporter map name - maximum 32 characters
+- `packet_length` (Number) Export Packet maximum L3 length, should conform to outgoing interface mtu
+- `source` (String) Source interface
+- `transport_udp` (Number) Use UDP as transport protocol
+- `version_export_format` (String) Specify export format
+- `version_options_class_table_timeout` (Number) Specify export timeout
+- `version_options_interface_table_timeout` (Number) Specify export timeout
+- `version_options_sampler_table_timeout` (Number) Specify export timeout
+- `version_options_vrf_table_timeout` (Number) Specify export timeout
+- `version_template_data_timeout` (Number) Specify custom timeout for the template
+- `version_template_options_timeout` (Number) Specify custom timeout for the template
+- `version_template_timeout` (Number) Specify custom timeout for the template
diff --git a/docs/guides/changelog.md b/docs/guides/changelog.md
index ee1469d4..34f4a7f8 100644
--- a/docs/guides/changelog.md
+++ b/docs/guides/changelog.md
@@ -33,6 +33,10 @@ description: |-
- Add `iosxr_rd_set` resource and data source
- Add `contact` and `location` attributes to `iosxr_snmp_server` resource and data source
- Add `police_conform_action_transmit`, `police_conform_action_drop`, `police_exceed_action_transmit`, `police_exceed_action_drop`, `police_violate_action_transmit`, `police_violate_action_drop` attributes to `iosxr_policy_map_qos` resource and data source
+- Add `iosxr_bfd` resource and data source
+- Add `iosxr_flow_exporter_map` resource and data source
+
+
## 0.2.1
diff --git a/docs/resources/bfd.md b/docs/resources/bfd.md
new file mode 100644
index 00000000..9dd7c444
--- /dev/null
+++ b/docs/resources/bfd.md
@@ -0,0 +1,141 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "iosxr_bfd Resource - terraform-provider-iosxr"
+subcategory: "System"
+description: |-
+ This resource can manage the BFD configuration.
+---
+
+# iosxr_bfd (Resource)
+
+This resource can manage the BFD configuration.
+
+## Example Usage
+
+```terraform
+resource "iosxr_bfd" "example" {
+ echo_disable = true
+ echo_latency_detect_percentage = 200
+ echo_latency_detect_count = 10
+ echo_startup_validate_force = true
+ echo_ipv4_source = "10.1.1.1"
+ echo_ipv4_bundle_per_member_minimum_interval_preferred_minimum_interval = 200
+ trap_singlehop_pre_mapped = true
+ multipath_locations = [
+ {
+ location_name = "0/0/CPU0"
+ }
+ ]
+ multihop_ttl_drop_threshold = 200
+ dampening_initial_wait = 3600
+ dampening_secondary_wait = 3200
+ dampening_maximum_wait = 3100
+ dampening_threshold = 60000
+ dampening_extensions_down_monitoring = true
+ dampening_disable = true
+ dampening_bundle_member_l3_only_mode = true
+ dampening_bundle_member_initial_wait = 5184
+ dampening_bundle_member_secondary_wait = 6184
+ dampening_bundle_member_maximum_wait = 7184
+ bundle_coexistence_bob_blb_inherit = false
+ bundle_coexistence_bob_blb_logical = true
+ interfaces = [
+ {
+ interface_name = "GigabitEthernet0/0/0/0"
+ echo_disable = true
+ echo_ipv4_source = "12.1.1.1"
+ ipv6_checksum_disable = true
+ disable = true
+ local_address = "33.33.31.1"
+ tx_interval = 3200
+ rx_interval = 4200
+ multiplier = 40
+ }
+ ]
+ ipv6_checksum_disable = true
+}
+```
+
+
+## Schema
+
+### Optional
+
+- `bundle_coexistence_bob_blb_inherit` (Boolean) Use inheritence mechanism
+- `bundle_coexistence_bob_blb_logical` (Boolean) Use BFD logical Bundle natively
+- `dampening_bundle_member_initial_wait` (Number) Initial delay before bringing up session
+ - Range: `1`-`518400000`
+- `dampening_bundle_member_l3_only_mode` (Boolean) Apply immediate dampening and only when failure is L3 specific
+- `dampening_bundle_member_maximum_wait` (Number) Maximum delay before bringing up session
+ - Range: `1`-`518400000`
+- `dampening_bundle_member_secondary_wait` (Number) Secondary delay before bringing up session
+ - Range: `1`-`518400000`
+- `dampening_disable` (Boolean) Disable BFD dampening
+- `dampening_extensions_down_monitoring` (Boolean) Enable DOWN state session monitoring extensions
+- `dampening_initial_wait` (Number) Initial delay before bringing up session
+ - Range: `1`-`3600000`
+- `dampening_maximum_wait` (Number) Maximum delay before bringing up session
+ - Range: `1`-`3600000`
+- `dampening_secondary_wait` (Number) Secondary delay before bringing up session
+ - Range: `1`-`3600000`
+- `dampening_threshold` (Number) Stability threshold to enable dampening
+ - Range: `60000`-`3600000`
+- `delete_mode` (String) Configure behavior when deleting/destroying the resource. Either delete the entire object (YANG container) being managed, or only delete the individual resource attributes configured explicitly and leave everything else as-is. Default value is `all`.
+ - Choices: `all`, `attributes`
+- `device` (String) A device name from the provider configuration.
+- `echo_disable` (Boolean) Disable BFD echo mode
+- `echo_ipv4_bundle_per_member_minimum_interval_preferred_minimum_interval` (Number) The preferred minimum interval (in ms) for the BFD session
+ - Range: `15`-`2000`
+- `echo_ipv4_source` (String) BFD echo source IP address
+- `echo_latency_detect_count` (Number) Count of consecutive bad latency packets to take session down
+ - Range: `1`-`10`
+- `echo_latency_detect_percentage` (Number) Percentage of detection time to consider as bad latency
+ - Range: `100`-`250`
+- `echo_startup_validate_force` (Boolean) Ignore remote 'Required Min Echo RX Interval' setting
+- `interfaces` (Attributes List) Configure BFD on an interface (see [below for nested schema](#nestedatt--interfaces))
+- `ipv6_checksum_disable` (Boolean) Disable BFD checksum
+- `multihop_ttl_drop_threshold` (Number) TTL Drop Threshold
+ - Range: `0`-`254`
+- `multipath_locations` (Attributes List) Specify a location (see [below for nested schema](#nestedatt--multipath_locations))
+- `trap_singlehop_pre_mapped` (Boolean) Configure BFD trap pre-mapped
+
+### Read-Only
+
+- `id` (String) The path of the object.
+
+
+### Nested Schema for `interfaces`
+
+Required:
+
+- `interface_name` (String) Configure BFD on an interface
+
+Optional:
+
+- `disable` (Boolean) Disable BFD for this interface
+- `echo_disable` (Boolean) Disable BFD echo mode for this interface
+- `echo_ipv4_source` (String) BFD echo source IP address
+- `ipv6_checksum_disable` (Boolean) Disable BFD ipv6 checksum mode for this interface
+- `local_address` (String) Local address to be used by BFD for this interface
+- `multiplier` (Number) BFD multiplier for this interface
+ - Range: `2`-`50`
+- `rx_interval` (Number) BFD RX Interval for this interface in microseconds
+ - Range: `3000`-`30000000`
+- `tx_interval` (Number) BFD TX Interval for this interface in microseconds
+ - Range: `3000`-`30000000`
+
+
+
+### Nested Schema for `multipath_locations`
+
+Required:
+
+- `location_name` (String) Specify a location
+
+## Import
+
+Import is supported using the following syntax:
+
+```shell
+terraform import iosxr_bfd.example "Cisco-IOS-XR-um-bfd-sbfd-cfg:/bfd"
+```
diff --git a/docs/resources/flow_exporter_map.md b/docs/resources/flow_exporter_map.md
new file mode 100644
index 00000000..87fad12c
--- /dev/null
+++ b/docs/resources/flow_exporter_map.md
@@ -0,0 +1,96 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "iosxr_flow_exporter_map Resource - terraform-provider-iosxr"
+subcategory: "Flow"
+description: |-
+ This resource can manage the Flow Exporter Map configuration.
+---
+
+# iosxr_flow_exporter_map (Resource)
+
+This resource can manage the Flow Exporter Map configuration.
+
+## Example Usage
+
+```terraform
+resource "iosxr_flow_exporter_map" "example" {
+ exporter_maps = [
+ {
+ exporter_map_name = "TEST"
+ destination_ipv4_address = "10.1.1.1"
+ destination_ipv6_address = "1::1"
+ destination_vrf = "28"
+ source = "10.1.1.4"
+ dscp = 62
+ packet_length = 512
+ transport_udp = 1033
+ dfbit_set = true
+ version_export_format = "true"
+ version_template_data_timeout = 1024
+ version_template_options_timeout = 3033
+ version_template_timeout = 2222
+ version_options_interface_table_timeout = 6048
+ version_options_sampler_table_timeout = 4096
+ version_options_class_table_timeout = 255
+ version_options_vrf_table_timeout = 122
+ }
+ ]
+}
+```
+
+
+## Schema
+
+### Optional
+
+- `device` (String) A device name from the provider configuration.
+- `exporter_maps` (Attributes List) Exporter map name - maximum 32 characters (see [below for nested schema](#nestedatt--exporter_maps))
+
+### Read-Only
+
+- `id` (String) The path of the object.
+
+
+### Nested Schema for `exporter_maps`
+
+Required:
+
+- `exporter_map_name` (String) Exporter map name - maximum 32 characters
+- `version_export_format` (String) Specify export format
+ - Choices: `ipfix`, `protobuf`, `sflow`, `v9`
+
+Optional:
+
+- `destination_ipv4_address` (String) Destination IPv4 address
+- `destination_ipv6_address` (String) Destination IPv6 address
+- `destination_vrf` (String) Configure VRF to be used for reaching export destination
+- `dfbit_set` (Boolean) Set Export Packet Do Not Fragment Flag
+- `dscp` (Number) Specify DSCP value for ipv4 export packets or traffic-class for ipv6 export packets
+ - Range: `0`-`63`
+- `packet_length` (Number) Export Packet maximum L3 length, should conform to outgoing interface mtu
+ - Range: `512`-`9000`
+- `source` (String) Source interface
+- `transport_udp` (Number) Use UDP as transport protocol
+ - Range: `1024`-`65535`
+- `version_options_class_table_timeout` (Number) Specify export timeout
+ - Range: `1`-`604800`
+- `version_options_interface_table_timeout` (Number) Specify export timeout
+ - Range: `1`-`604800`
+- `version_options_sampler_table_timeout` (Number) Specify export timeout
+ - Range: `1`-`604800`
+- `version_options_vrf_table_timeout` (Number) Specify export timeout
+ - Range: `1`-`604800`
+- `version_template_data_timeout` (Number) Specify custom timeout for the template
+ - Range: `1`-`604800`
+- `version_template_options_timeout` (Number) Specify custom timeout for the template
+ - Range: `1`-`604800`
+- `version_template_timeout` (Number) Specify custom timeout for the template
+ - Range: `1`-`604800`
+
+## Import
+
+Import is supported using the following syntax:
+
+```shell
+terraform import iosxr_flow_exporter_map.example "Cisco-IOS-XR-um-flow-cfg:/flow/exporter-maps"
+```
diff --git a/examples/data-sources/iosxr_bfd/data-source.tf b/examples/data-sources/iosxr_bfd/data-source.tf
new file mode 100644
index 00000000..283a36f4
--- /dev/null
+++ b/examples/data-sources/iosxr_bfd/data-source.tf
@@ -0,0 +1,2 @@
+data "iosxr_bfd" "example" {
+}
diff --git a/examples/data-sources/iosxr_flow_exporter_map/data-source.tf b/examples/data-sources/iosxr_flow_exporter_map/data-source.tf
new file mode 100644
index 00000000..cb42cec4
--- /dev/null
+++ b/examples/data-sources/iosxr_flow_exporter_map/data-source.tf
@@ -0,0 +1,2 @@
+data "iosxr_flow_exporter_map" "example" {
+}
diff --git a/examples/resources/iosxr_bfd/import.sh b/examples/resources/iosxr_bfd/import.sh
new file mode 100644
index 00000000..b3d7c030
--- /dev/null
+++ b/examples/resources/iosxr_bfd/import.sh
@@ -0,0 +1 @@
+terraform import iosxr_bfd.example "Cisco-IOS-XR-um-bfd-sbfd-cfg:/bfd"
diff --git a/examples/resources/iosxr_bfd/resource.tf b/examples/resources/iosxr_bfd/resource.tf
new file mode 100644
index 00000000..cd8a8fa1
--- /dev/null
+++ b/examples/resources/iosxr_bfd/resource.tf
@@ -0,0 +1,41 @@
+resource "iosxr_bfd" "example" {
+ echo_disable = true
+ echo_latency_detect_percentage = 200
+ echo_latency_detect_count = 10
+ echo_startup_validate_force = true
+ echo_ipv4_source = "10.1.1.1"
+ echo_ipv4_bundle_per_member_minimum_interval_preferred_minimum_interval = 200
+ trap_singlehop_pre_mapped = true
+ multipath_locations = [
+ {
+ location_name = "0/0/CPU0"
+ }
+ ]
+ multihop_ttl_drop_threshold = 200
+ dampening_initial_wait = 3600
+ dampening_secondary_wait = 3200
+ dampening_maximum_wait = 3100
+ dampening_threshold = 60000
+ dampening_extensions_down_monitoring = true
+ dampening_disable = true
+ dampening_bundle_member_l3_only_mode = true
+ dampening_bundle_member_initial_wait = 5184
+ dampening_bundle_member_secondary_wait = 6184
+ dampening_bundle_member_maximum_wait = 7184
+ bundle_coexistence_bob_blb_inherit = false
+ bundle_coexistence_bob_blb_logical = true
+ interfaces = [
+ {
+ interface_name = "GigabitEthernet0/0/0/0"
+ echo_disable = true
+ echo_ipv4_source = "12.1.1.1"
+ ipv6_checksum_disable = true
+ disable = true
+ local_address = "33.33.31.1"
+ tx_interval = 3200
+ rx_interval = 4200
+ multiplier = 40
+ }
+ ]
+ ipv6_checksum_disable = true
+}
diff --git a/examples/resources/iosxr_flow_exporter_map/import.sh b/examples/resources/iosxr_flow_exporter_map/import.sh
new file mode 100644
index 00000000..95a28347
--- /dev/null
+++ b/examples/resources/iosxr_flow_exporter_map/import.sh
@@ -0,0 +1 @@
+terraform import iosxr_flow_exporter_map.example "Cisco-IOS-XR-um-flow-cfg:/flow/exporter-maps"
diff --git a/examples/resources/iosxr_flow_exporter_map/resource.tf b/examples/resources/iosxr_flow_exporter_map/resource.tf
new file mode 100644
index 00000000..953cb32c
--- /dev/null
+++ b/examples/resources/iosxr_flow_exporter_map/resource.tf
@@ -0,0 +1,23 @@
+resource "iosxr_flow_exporter_map" "example" {
+ exporter_maps = [
+ {
+ exporter_map_name = "TEST"
+ destination_ipv4_address = "10.1.1.1"
+ destination_ipv6_address = "1::1"
+ destination_vrf = "28"
+ source = "10.1.1.4"
+ dscp = 62
+ packet_length = 512
+ transport_udp = 1033
+ dfbit_set = true
+ version_export_format = "true"
+ version_template_data_timeout = 1024
+ version_template_options_timeout = 3033
+ version_template_timeout = 2222
+ version_options_interface_table_timeout = 6048
+ version_options_sampler_table_timeout = 4096
+ version_options_class_table_timeout = 255
+ version_options_vrf_table_timeout = 122
+ }
+ ]
+}
diff --git a/gen/definitions/bfd.yaml b/gen/definitions/bfd.yaml
new file mode 100644
index 00000000..400a4f6b
--- /dev/null
+++ b/gen/definitions/bfd.yaml
@@ -0,0 +1,78 @@
+---
+name: BFD
+path: Cisco-IOS-XR-um-bfd-sbfd-cfg:/bfd
+doc_category: System
+attributes:
+ - yang_name: echo/disable
+ example: true
+ - yang_name: echo/latency/detect/percentage
+ example: 200
+ - yang_name: echo/latency/detect/count
+ example: 10
+ - yang_name: echo/startup/validate/force
+ example: true
+ - yang_name: echo/ipv4/source
+ example: 10.1.1.1
+ - yang_name: echo/ipv4/bundle-per-member/minimum-interval/preferred-minimum-interval
+ example: 200
+ - yang_name: trap/singlehop/pre-mapped
+ example: true
+ - yang_name: multipath/include/locations/location
+ tf_name: multipath_locations
+ type: List
+ attributes:
+ - yang_name: location-name
+ id: true
+ example: 0/0/CPU0
+
+ - yang_name: multihop/ttl-drop-threshold
+ example: 200
+ - yang_name: dampening/initial-wait
+ example: 3600
+ - yang_name: dampening/secondary-wait
+ example: 3200
+ - yang_name: dampening/maximum-wait
+ example: 3100
+ - yang_name: dampening/threshold
+ example: 60000
+ - yang_name: dampening/extensions/down-monitoring
+ example: true
+ - yang_name: dampening/disable
+ example: true
+ - yang_name: dampening/bundle-member/l3-only-mode
+ example: true
+ - yang_name: dampening/bundle-member/initial-wait
+ example: 5184
+ - yang_name: dampening/bundle-member/secondary-wait
+ example: 6184
+ - yang_name: dampening/bundle-member/maximum-wait
+ example: 7184
+ - yang_name: bundle/coexistence/bob-blb/inherit
+ example: false
+ - yang_name: bundle/coexistence/bob-blb/logical
+ example: true
+ - yang_name: interfaces/interface
+ tf_name: interfaces
+ type: List
+ attributes:
+ - yang_name: interface-name
+ id: true
+ example: GigabitEthernet0/0/0/0
+ - yang_name: echo/disable
+ example: true
+ - yang_name: echo/ipv4/source
+ example: 12.1.1.1
+ - yang_name: ipv6/checksum/disable
+ example: true
+ - yang_name: disable
+ example: true
+ - yang_name: local-address
+ example: 33.33.31.1
+ - yang_name: tx-interval
+ example: 3200
+ - yang_name: rx-interval
+ example: 4200
+ - yang_name: multiplier
+ example: 40
+ - yang_name: ipv6/checksum/disable
+ example: true
\ No newline at end of file
diff --git a/gen/definitions/flow_exporter_map.yaml b/gen/definitions/flow_exporter_map.yaml
new file mode 100644
index 00000000..015036fa
--- /dev/null
+++ b/gen/definitions/flow_exporter_map.yaml
@@ -0,0 +1,50 @@
+---
+name: Flow Exporter Map
+path: Cisco-IOS-XR-um-flow-cfg:/flow/exporter-maps
+doc_category: Flow
+no_delete_attributes: true
+attributes:
+ - yang_name: exporter-map
+ tf_name: exporter_maps
+ type: List
+ attributes:
+ - yang_name: exporter-map-name
+ id: true
+ example: TEST
+ - yang_name: destination/ipv4-address
+ example: 10.1.1.1
+ - yang_name: destination/ipv6-address
+ example: 1::1
+ - yang_name: destination/vrf
+ example: 28
+ - yang_name: source
+ example: 10.1.1.4
+ - yang_name: dscp
+ example: 62
+ - yang_name: packet-length
+ example: 512
+ # - yang_name: source-address/ipv4-address
+ # example: 20.1.1.1
+ # - yang_name: source-address/ipv6-address
+ # example: 2::2
+ # exclude_test: true
+ - yang_name: transport/udp
+ example: 1033
+ - yang_name: dfbit/set
+ example: true
+ - yang_name: version/export-format
+ example: true
+ - yang_name: version/template/data/timeout
+ example: 1024
+ - yang_name: version/template/options/timeout
+ example: 3033
+ - yang_name: version/template/timeout
+ example: 2222
+ - yang_name: version/options/interface-table/timeout
+ example: 6048
+ - yang_name: version/options/sampler-table/timeout
+ example: 4096
+ - yang_name: version/options/class-table/timeout
+ example: 255
+ - yang_name: version/options/vrf-table/timeout
+ example: 122
\ No newline at end of file
diff --git a/gen/load_models.go b/gen/load_models.go
index 3533cbec..42de1644 100644
--- a/gen/load_models.go
+++ b/gen/load_models.go
@@ -56,6 +56,7 @@ var models = []string{
"https://raw.githubusercontent.com/YangModels/yang/main/vendor/cisco/xr/761/Cisco-IOS-XR-um-traps-entity-state-cfg.yang",
"https://raw.githubusercontent.com/YangModels/yang/main/vendor/cisco/xr/761/Cisco-IOS-XR-um-traps-entity-redundancy-cfg.yang",
"https://raw.githubusercontent.com/YangModels/yang/main/vendor/cisco/xr/761/Cisco-IOS-XR-um-l2vpn-cfg.yang",
+ "https://raw.githubusercontent.com/YangModels/yang/main/vendor/cisco/xr/761/Cisco-IOS-XR-um-flow-cfg.yang",
"https://raw.githubusercontent.com/YangModels/yang/main/vendor/cisco/xr/761/Cisco-IOS-XR-um-mibs-ifmib-cfg.yang",
"https://raw.githubusercontent.com/YangModels/yang/main/vendor/cisco/xr/761/Cisco-IOS-XR-um-traps-mpls-ldp-cfg.yang",
"https://raw.githubusercontent.com/YangModels/yang/main/vendor/cisco/xr/761/Cisco-IOS-XR-um-ipv4-access-list-cfg.yang",
diff --git a/internal/provider/data_source_iosxr_bfd.go b/internal/provider/data_source_iosxr_bfd.go
new file mode 100644
index 00000000..2025237a
--- /dev/null
+++ b/internal/provider/data_source_iosxr_bfd.go
@@ -0,0 +1,242 @@
+// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+// Code generated by "gen/generator.go"; DO NOT EDIT.
+
+package provider
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/CiscoDevNet/terraform-provider-iosxr/internal/provider/client"
+ "github.com/hashicorp/terraform-plugin-framework/datasource"
+ "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
+)
+
+// Ensure the implementation satisfies the expected interfaces.
+var (
+ _ datasource.DataSource = &BFDDataSource{}
+ _ datasource.DataSourceWithConfigure = &BFDDataSource{}
+)
+
+func NewBFDDataSource() datasource.DataSource {
+ return &BFDDataSource{}
+}
+
+type BFDDataSource struct {
+ client *client.Client
+}
+
+func (d *BFDDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_bfd"
+}
+
+func (d *BFDDataSource) 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 BFD configuration.",
+
+ Attributes: map[string]schema.Attribute{
+ "device": schema.StringAttribute{
+ MarkdownDescription: "A device name from the provider configuration.",
+ Optional: true,
+ },
+ "id": schema.StringAttribute{
+ MarkdownDescription: "The path of the retrieved object.",
+ Computed: true,
+ },
+ "echo_disable": schema.BoolAttribute{
+ MarkdownDescription: "Disable BFD echo mode",
+ Computed: true,
+ },
+ "echo_latency_detect_percentage": schema.Int64Attribute{
+ MarkdownDescription: "Percentage of detection time to consider as bad latency",
+ Computed: true,
+ },
+ "echo_latency_detect_count": schema.Int64Attribute{
+ MarkdownDescription: "Count of consecutive bad latency packets to take session down",
+ Computed: true,
+ },
+ "echo_startup_validate_force": schema.BoolAttribute{
+ MarkdownDescription: "Ignore remote 'Required Min Echo RX Interval' setting",
+ Computed: true,
+ },
+ "echo_ipv4_source": schema.StringAttribute{
+ MarkdownDescription: "BFD echo source IP address",
+ Computed: true,
+ },
+ "echo_ipv4_bundle_per_member_minimum_interval_preferred_minimum_interval": schema.Int64Attribute{
+ MarkdownDescription: "The preferred minimum interval (in ms) for the BFD session",
+ Computed: true,
+ },
+ "trap_singlehop_pre_mapped": schema.BoolAttribute{
+ MarkdownDescription: "Configure BFD trap pre-mapped",
+ Computed: true,
+ },
+ "multipath_locations": schema.ListNestedAttribute{
+ MarkdownDescription: "Specify a location",
+ Computed: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "location_name": schema.StringAttribute{
+ MarkdownDescription: "Specify a location",
+ Computed: true,
+ },
+ },
+ },
+ },
+ "multihop_ttl_drop_threshold": schema.Int64Attribute{
+ MarkdownDescription: "TTL Drop Threshold",
+ Computed: true,
+ },
+ "dampening_initial_wait": schema.Int64Attribute{
+ MarkdownDescription: "Initial delay before bringing up session",
+ Computed: true,
+ },
+ "dampening_secondary_wait": schema.Int64Attribute{
+ MarkdownDescription: "Secondary delay before bringing up session",
+ Computed: true,
+ },
+ "dampening_maximum_wait": schema.Int64Attribute{
+ MarkdownDescription: "Maximum delay before bringing up session",
+ Computed: true,
+ },
+ "dampening_threshold": schema.Int64Attribute{
+ MarkdownDescription: "Stability threshold to enable dampening",
+ Computed: true,
+ },
+ "dampening_extensions_down_monitoring": schema.BoolAttribute{
+ MarkdownDescription: "Enable DOWN state session monitoring extensions",
+ Computed: true,
+ },
+ "dampening_disable": schema.BoolAttribute{
+ MarkdownDescription: "Disable BFD dampening",
+ Computed: true,
+ },
+ "dampening_bundle_member_l3_only_mode": schema.BoolAttribute{
+ MarkdownDescription: "Apply immediate dampening and only when failure is L3 specific",
+ Computed: true,
+ },
+ "dampening_bundle_member_initial_wait": schema.Int64Attribute{
+ MarkdownDescription: "Initial delay before bringing up session",
+ Computed: true,
+ },
+ "dampening_bundle_member_secondary_wait": schema.Int64Attribute{
+ MarkdownDescription: "Secondary delay before bringing up session",
+ Computed: true,
+ },
+ "dampening_bundle_member_maximum_wait": schema.Int64Attribute{
+ MarkdownDescription: "Maximum delay before bringing up session",
+ Computed: true,
+ },
+ "bundle_coexistence_bob_blb_inherit": schema.BoolAttribute{
+ MarkdownDescription: "Use inheritence mechanism",
+ Computed: true,
+ },
+ "bundle_coexistence_bob_blb_logical": schema.BoolAttribute{
+ MarkdownDescription: "Use BFD logical Bundle natively",
+ Computed: true,
+ },
+ "interfaces": schema.ListNestedAttribute{
+ MarkdownDescription: "Configure BFD on an interface",
+ Computed: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "interface_name": schema.StringAttribute{
+ MarkdownDescription: "Configure BFD on an interface",
+ Computed: true,
+ },
+ "echo_disable": schema.BoolAttribute{
+ MarkdownDescription: "Disable BFD echo mode for this interface",
+ Computed: true,
+ },
+ "echo_ipv4_source": schema.StringAttribute{
+ MarkdownDescription: "BFD echo source IP address",
+ Computed: true,
+ },
+ "ipv6_checksum_disable": schema.BoolAttribute{
+ MarkdownDescription: "Disable BFD ipv6 checksum mode for this interface",
+ Computed: true,
+ },
+ "disable": schema.BoolAttribute{
+ MarkdownDescription: "Disable BFD for this interface",
+ Computed: true,
+ },
+ "local_address": schema.StringAttribute{
+ MarkdownDescription: "Local address to be used by BFD for this interface",
+ Computed: true,
+ },
+ "tx_interval": schema.Int64Attribute{
+ MarkdownDescription: "BFD TX Interval for this interface in microseconds",
+ Computed: true,
+ },
+ "rx_interval": schema.Int64Attribute{
+ MarkdownDescription: "BFD RX Interval for this interface in microseconds",
+ Computed: true,
+ },
+ "multiplier": schema.Int64Attribute{
+ MarkdownDescription: "BFD multiplier for this interface",
+ Computed: true,
+ },
+ },
+ },
+ },
+ "ipv6_checksum_disable": schema.BoolAttribute{
+ MarkdownDescription: "Disable BFD checksum",
+ Computed: true,
+ },
+ },
+ }
+}
+
+func (d *BFDDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) {
+ if req.ProviderData == nil {
+ return
+ }
+
+ d.client = req.ProviderData.(*client.Client)
+}
+
+func (d *BFDDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
+ var config BFDData
+
+ // Read config
+ diags := req.Config.Get(ctx, &config)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", config.getPath()))
+
+ getResp, diags := d.client.Get(ctx, config.Device.ValueString(), config.getPath())
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal())
+ config.Id = types.StringValue(config.getPath())
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", config.getPath()))
+
+ diags = resp.State.Set(ctx, &config)
+ resp.Diagnostics.Append(diags...)
+}
diff --git a/internal/provider/data_source_iosxr_bfd_test.go b/internal/provider/data_source_iosxr_bfd_test.go
new file mode 100644
index 00000000..3e340b77
--- /dev/null
+++ b/internal/provider/data_source_iosxr_bfd_test.go
@@ -0,0 +1,119 @@
+// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+// Code generated by "gen/generator.go"; DO NOT EDIT.
+
+package provider
+
+import (
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+func TestAccDataSourceIosxrBFD(t *testing.T) {
+ var checks []resource.TestCheckFunc
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "echo_disable", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "echo_latency_detect_percentage", "200"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "echo_latency_detect_count", "10"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "echo_startup_validate_force", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "echo_ipv4_source", "10.1.1.1"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "echo_ipv4_bundle_per_member_minimum_interval_preferred_minimum_interval", "200"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "trap_singlehop_pre_mapped", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "multipath_locations.0.location_name", "0/0/CPU0"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "multihop_ttl_drop_threshold", "200"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "dampening_initial_wait", "3600"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "dampening_secondary_wait", "3200"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "dampening_maximum_wait", "3100"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "dampening_threshold", "60000"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "dampening_extensions_down_monitoring", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "dampening_disable", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "dampening_bundle_member_l3_only_mode", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "dampening_bundle_member_initial_wait", "5184"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "dampening_bundle_member_secondary_wait", "6184"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "dampening_bundle_member_maximum_wait", "7184"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "bundle_coexistence_bob_blb_inherit", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "bundle_coexistence_bob_blb_logical", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "interfaces.0.interface_name", "GigabitEthernet0/0/0/0"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "interfaces.0.echo_disable", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "interfaces.0.echo_ipv4_source", "12.1.1.1"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "interfaces.0.ipv6_checksum_disable", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "interfaces.0.disable", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "interfaces.0.local_address", "33.33.31.1"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "interfaces.0.tx_interval", "3200"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "interfaces.0.rx_interval", "4200"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "interfaces.0.multiplier", "40"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_bfd.test", "ipv6_checksum_disable", "true"))
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: testAccDataSourceIosxrBFDConfig(),
+ Check: resource.ComposeTestCheckFunc(checks...),
+ },
+ },
+ })
+}
+
+func testAccDataSourceIosxrBFDConfig() string {
+ config := `resource "iosxr_bfd" "test" {` + "\n"
+ config += ` delete_mode = "attributes"` + "\n"
+ config += ` echo_disable = true` + "\n"
+ config += ` echo_latency_detect_percentage = 200` + "\n"
+ config += ` echo_latency_detect_count = 10` + "\n"
+ config += ` echo_startup_validate_force = true` + "\n"
+ config += ` echo_ipv4_source = "10.1.1.1"` + "\n"
+ config += ` echo_ipv4_bundle_per_member_minimum_interval_preferred_minimum_interval = 200` + "\n"
+ config += ` trap_singlehop_pre_mapped = true` + "\n"
+ config += ` multipath_locations = [{` + "\n"
+ config += ` location_name = "0/0/CPU0"` + "\n"
+ config += ` }]` + "\n"
+ config += ` multihop_ttl_drop_threshold = 200` + "\n"
+ config += ` dampening_initial_wait = 3600` + "\n"
+ config += ` dampening_secondary_wait = 3200` + "\n"
+ config += ` dampening_maximum_wait = 3100` + "\n"
+ config += ` dampening_threshold = 60000` + "\n"
+ config += ` dampening_extensions_down_monitoring = true` + "\n"
+ config += ` dampening_disable = true` + "\n"
+ config += ` dampening_bundle_member_l3_only_mode = true` + "\n"
+ config += ` dampening_bundle_member_initial_wait = 5184` + "\n"
+ config += ` dampening_bundle_member_secondary_wait = 6184` + "\n"
+ config += ` dampening_bundle_member_maximum_wait = 7184` + "\n"
+ config += ` bundle_coexistence_bob_blb_inherit = false` + "\n"
+ config += ` bundle_coexistence_bob_blb_logical = true` + "\n"
+ config += ` interfaces = [{` + "\n"
+ config += ` interface_name = "GigabitEthernet0/0/0/0"` + "\n"
+ config += ` echo_disable = true` + "\n"
+ config += ` echo_ipv4_source = "12.1.1.1"` + "\n"
+ config += ` ipv6_checksum_disable = true` + "\n"
+ config += ` disable = true` + "\n"
+ config += ` local_address = "33.33.31.1"` + "\n"
+ config += ` tx_interval = 3200` + "\n"
+ config += ` rx_interval = 4200` + "\n"
+ config += ` multiplier = 40` + "\n"
+ config += ` }]` + "\n"
+ config += ` ipv6_checksum_disable = true` + "\n"
+ config += `}` + "\n"
+
+ config += `
+ data "iosxr_bfd" "test" {
+ depends_on = [iosxr_bfd.test]
+ }
+ `
+ return config
+}
diff --git a/internal/provider/data_source_iosxr_flow_exporter_map.go b/internal/provider/data_source_iosxr_flow_exporter_map.go
new file mode 100644
index 00000000..ee61255c
--- /dev/null
+++ b/internal/provider/data_source_iosxr_flow_exporter_map.go
@@ -0,0 +1,178 @@
+// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+// Code generated by "gen/generator.go"; DO NOT EDIT.
+
+package provider
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/CiscoDevNet/terraform-provider-iosxr/internal/provider/client"
+ "github.com/hashicorp/terraform-plugin-framework/datasource"
+ "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
+)
+
+// Ensure the implementation satisfies the expected interfaces.
+var (
+ _ datasource.DataSource = &FlowExporterMapDataSource{}
+ _ datasource.DataSourceWithConfigure = &FlowExporterMapDataSource{}
+)
+
+func NewFlowExporterMapDataSource() datasource.DataSource {
+ return &FlowExporterMapDataSource{}
+}
+
+type FlowExporterMapDataSource struct {
+ client *client.Client
+}
+
+func (d *FlowExporterMapDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_flow_exporter_map"
+}
+
+func (d *FlowExporterMapDataSource) 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 Flow Exporter Map configuration.",
+
+ Attributes: map[string]schema.Attribute{
+ "device": schema.StringAttribute{
+ MarkdownDescription: "A device name from the provider configuration.",
+ Optional: true,
+ },
+ "id": schema.StringAttribute{
+ MarkdownDescription: "The path of the retrieved object.",
+ Computed: true,
+ },
+ "exporter_maps": schema.ListNestedAttribute{
+ MarkdownDescription: "Exporter map name - maximum 32 characters",
+ Computed: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "exporter_map_name": schema.StringAttribute{
+ MarkdownDescription: "Exporter map name - maximum 32 characters",
+ Computed: true,
+ },
+ "destination_ipv4_address": schema.StringAttribute{
+ MarkdownDescription: "Destination IPv4 address",
+ Computed: true,
+ },
+ "destination_ipv6_address": schema.StringAttribute{
+ MarkdownDescription: "Destination IPv6 address",
+ Computed: true,
+ },
+ "destination_vrf": schema.StringAttribute{
+ MarkdownDescription: "Configure VRF to be used for reaching export destination",
+ Computed: true,
+ },
+ "source": schema.StringAttribute{
+ MarkdownDescription: "Source interface",
+ Computed: true,
+ },
+ "dscp": schema.Int64Attribute{
+ MarkdownDescription: "Specify DSCP value for ipv4 export packets or traffic-class for ipv6 export packets",
+ Computed: true,
+ },
+ "packet_length": schema.Int64Attribute{
+ MarkdownDescription: "Export Packet maximum L3 length, should conform to outgoing interface mtu",
+ Computed: true,
+ },
+ "transport_udp": schema.Int64Attribute{
+ MarkdownDescription: "Use UDP as transport protocol",
+ Computed: true,
+ },
+ "dfbit_set": schema.BoolAttribute{
+ MarkdownDescription: "Set Export Packet Do Not Fragment Flag",
+ Computed: true,
+ },
+ "version_export_format": schema.StringAttribute{
+ MarkdownDescription: "Specify export format",
+ Computed: true,
+ },
+ "version_template_data_timeout": schema.Int64Attribute{
+ MarkdownDescription: "Specify custom timeout for the template",
+ Computed: true,
+ },
+ "version_template_options_timeout": schema.Int64Attribute{
+ MarkdownDescription: "Specify custom timeout for the template",
+ Computed: true,
+ },
+ "version_template_timeout": schema.Int64Attribute{
+ MarkdownDescription: "Specify custom timeout for the template",
+ Computed: true,
+ },
+ "version_options_interface_table_timeout": schema.Int64Attribute{
+ MarkdownDescription: "Specify export timeout",
+ Computed: true,
+ },
+ "version_options_sampler_table_timeout": schema.Int64Attribute{
+ MarkdownDescription: "Specify export timeout",
+ Computed: true,
+ },
+ "version_options_class_table_timeout": schema.Int64Attribute{
+ MarkdownDescription: "Specify export timeout",
+ Computed: true,
+ },
+ "version_options_vrf_table_timeout": schema.Int64Attribute{
+ MarkdownDescription: "Specify export timeout",
+ Computed: true,
+ },
+ },
+ },
+ },
+ },
+ }
+}
+
+func (d *FlowExporterMapDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) {
+ if req.ProviderData == nil {
+ return
+ }
+
+ d.client = req.ProviderData.(*client.Client)
+}
+
+func (d *FlowExporterMapDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
+ var config FlowExporterMapData
+
+ // Read config
+ diags := req.Config.Get(ctx, &config)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", config.getPath()))
+
+ getResp, diags := d.client.Get(ctx, config.Device.ValueString(), config.getPath())
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ config.fromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal())
+ config.Id = types.StringValue(config.getPath())
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", config.getPath()))
+
+ diags = resp.State.Set(ctx, &config)
+ resp.Diagnostics.Append(diags...)
+}
diff --git a/internal/provider/data_source_iosxr_flow_exporter_map_test.go b/internal/provider/data_source_iosxr_flow_exporter_map_test.go
new file mode 100644
index 00000000..aa66346e
--- /dev/null
+++ b/internal/provider/data_source_iosxr_flow_exporter_map_test.go
@@ -0,0 +1,88 @@
+// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+// Code generated by "gen/generator.go"; DO NOT EDIT.
+
+package provider
+
+import (
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+func TestAccDataSourceIosxrFlowExporterMap(t *testing.T) {
+ var checks []resource.TestCheckFunc
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.exporter_map_name", "TEST"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.destination_ipv4_address", "10.1.1.1"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.destination_ipv6_address", "1::1"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.destination_vrf", "28"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.source", "10.1.1.4"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.dscp", "62"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.packet_length", "512"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.transport_udp", "1033"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.dfbit_set", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.version_export_format", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.version_template_data_timeout", "1024"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.version_template_options_timeout", "3033"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.version_template_timeout", "2222"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.version_options_interface_table_timeout", "6048"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.version_options_sampler_table_timeout", "4096"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.version_options_class_table_timeout", "255"))
+ checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_flow_exporter_map.test", "exporter_maps.0.version_options_vrf_table_timeout", "122"))
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: []resource.TestStep{
+ {
+ Config: testAccDataSourceIosxrFlowExporterMapConfig(),
+ Check: resource.ComposeTestCheckFunc(checks...),
+ },
+ },
+ })
+}
+
+func testAccDataSourceIosxrFlowExporterMapConfig() string {
+ config := `resource "iosxr_flow_exporter_map" "test" {` + "\n"
+ config += ` exporter_maps = [{` + "\n"
+ config += ` exporter_map_name = "TEST"` + "\n"
+ config += ` destination_ipv4_address = "10.1.1.1"` + "\n"
+ config += ` destination_ipv6_address = "1::1"` + "\n"
+ config += ` destination_vrf = "28"` + "\n"
+ config += ` source = "10.1.1.4"` + "\n"
+ config += ` dscp = 62` + "\n"
+ config += ` packet_length = 512` + "\n"
+ config += ` transport_udp = 1033` + "\n"
+ config += ` dfbit_set = true` + "\n"
+ config += ` version_export_format = "true"` + "\n"
+ config += ` version_template_data_timeout = 1024` + "\n"
+ config += ` version_template_options_timeout = 3033` + "\n"
+ config += ` version_template_timeout = 2222` + "\n"
+ config += ` version_options_interface_table_timeout = 6048` + "\n"
+ config += ` version_options_sampler_table_timeout = 4096` + "\n"
+ config += ` version_options_class_table_timeout = 255` + "\n"
+ config += ` version_options_vrf_table_timeout = 122` + "\n"
+ config += ` }]` + "\n"
+ config += `}` + "\n"
+
+ config += `
+ data "iosxr_flow_exporter_map" "test" {
+ depends_on = [iosxr_flow_exporter_map.test]
+ }
+ `
+ return config
+}
diff --git a/internal/provider/model_iosxr_bfd.go b/internal/provider/model_iosxr_bfd.go
new file mode 100644
index 00000000..ceb93dba
--- /dev/null
+++ b/internal/provider/model_iosxr_bfd.go
@@ -0,0 +1,842 @@
+// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+// Code generated by "gen/generator.go"; DO NOT EDIT.
+
+package provider
+
+import (
+ "context"
+ "fmt"
+ "reflect"
+ "strconv"
+
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/tidwall/gjson"
+ "github.com/tidwall/sjson"
+)
+
+type BFD struct {
+ Device types.String `tfsdk:"device"`
+ Id types.String `tfsdk:"id"`
+ DeleteMode types.String `tfsdk:"delete_mode"`
+ EchoDisable types.Bool `tfsdk:"echo_disable"`
+ EchoLatencyDetectPercentage types.Int64 `tfsdk:"echo_latency_detect_percentage"`
+ EchoLatencyDetectCount types.Int64 `tfsdk:"echo_latency_detect_count"`
+ EchoStartupValidateForce types.Bool `tfsdk:"echo_startup_validate_force"`
+ EchoIpv4Source types.String `tfsdk:"echo_ipv4_source"`
+ EchoIpv4BundlePerMemberMinimumIntervalPreferredMinimumInterval types.Int64 `tfsdk:"echo_ipv4_bundle_per_member_minimum_interval_preferred_minimum_interval"`
+ TrapSinglehopPreMapped types.Bool `tfsdk:"trap_singlehop_pre_mapped"`
+ MultipathLocations []BFDMultipathLocations `tfsdk:"multipath_locations"`
+ MultihopTtlDropThreshold types.Int64 `tfsdk:"multihop_ttl_drop_threshold"`
+ DampeningInitialWait types.Int64 `tfsdk:"dampening_initial_wait"`
+ DampeningSecondaryWait types.Int64 `tfsdk:"dampening_secondary_wait"`
+ DampeningMaximumWait types.Int64 `tfsdk:"dampening_maximum_wait"`
+ DampeningThreshold types.Int64 `tfsdk:"dampening_threshold"`
+ DampeningExtensionsDownMonitoring types.Bool `tfsdk:"dampening_extensions_down_monitoring"`
+ DampeningDisable types.Bool `tfsdk:"dampening_disable"`
+ DampeningBundleMemberL3OnlyMode types.Bool `tfsdk:"dampening_bundle_member_l3_only_mode"`
+ DampeningBundleMemberInitialWait types.Int64 `tfsdk:"dampening_bundle_member_initial_wait"`
+ DampeningBundleMemberSecondaryWait types.Int64 `tfsdk:"dampening_bundle_member_secondary_wait"`
+ DampeningBundleMemberMaximumWait types.Int64 `tfsdk:"dampening_bundle_member_maximum_wait"`
+ BundleCoexistenceBobBlbInherit types.Bool `tfsdk:"bundle_coexistence_bob_blb_inherit"`
+ BundleCoexistenceBobBlbLogical types.Bool `tfsdk:"bundle_coexistence_bob_blb_logical"`
+ Interfaces []BFDInterfaces `tfsdk:"interfaces"`
+ Ipv6ChecksumDisable types.Bool `tfsdk:"ipv6_checksum_disable"`
+}
+
+type BFDData struct {
+ Device types.String `tfsdk:"device"`
+ Id types.String `tfsdk:"id"`
+ EchoDisable types.Bool `tfsdk:"echo_disable"`
+ EchoLatencyDetectPercentage types.Int64 `tfsdk:"echo_latency_detect_percentage"`
+ EchoLatencyDetectCount types.Int64 `tfsdk:"echo_latency_detect_count"`
+ EchoStartupValidateForce types.Bool `tfsdk:"echo_startup_validate_force"`
+ EchoIpv4Source types.String `tfsdk:"echo_ipv4_source"`
+ EchoIpv4BundlePerMemberMinimumIntervalPreferredMinimumInterval types.Int64 `tfsdk:"echo_ipv4_bundle_per_member_minimum_interval_preferred_minimum_interval"`
+ TrapSinglehopPreMapped types.Bool `tfsdk:"trap_singlehop_pre_mapped"`
+ MultipathLocations []BFDMultipathLocations `tfsdk:"multipath_locations"`
+ MultihopTtlDropThreshold types.Int64 `tfsdk:"multihop_ttl_drop_threshold"`
+ DampeningInitialWait types.Int64 `tfsdk:"dampening_initial_wait"`
+ DampeningSecondaryWait types.Int64 `tfsdk:"dampening_secondary_wait"`
+ DampeningMaximumWait types.Int64 `tfsdk:"dampening_maximum_wait"`
+ DampeningThreshold types.Int64 `tfsdk:"dampening_threshold"`
+ DampeningExtensionsDownMonitoring types.Bool `tfsdk:"dampening_extensions_down_monitoring"`
+ DampeningDisable types.Bool `tfsdk:"dampening_disable"`
+ DampeningBundleMemberL3OnlyMode types.Bool `tfsdk:"dampening_bundle_member_l3_only_mode"`
+ DampeningBundleMemberInitialWait types.Int64 `tfsdk:"dampening_bundle_member_initial_wait"`
+ DampeningBundleMemberSecondaryWait types.Int64 `tfsdk:"dampening_bundle_member_secondary_wait"`
+ DampeningBundleMemberMaximumWait types.Int64 `tfsdk:"dampening_bundle_member_maximum_wait"`
+ BundleCoexistenceBobBlbInherit types.Bool `tfsdk:"bundle_coexistence_bob_blb_inherit"`
+ BundleCoexistenceBobBlbLogical types.Bool `tfsdk:"bundle_coexistence_bob_blb_logical"`
+ Interfaces []BFDInterfaces `tfsdk:"interfaces"`
+ Ipv6ChecksumDisable types.Bool `tfsdk:"ipv6_checksum_disable"`
+}
+type BFDMultipathLocations struct {
+ LocationName types.String `tfsdk:"location_name"`
+}
+type BFDInterfaces struct {
+ InterfaceName types.String `tfsdk:"interface_name"`
+ EchoDisable types.Bool `tfsdk:"echo_disable"`
+ EchoIpv4Source types.String `tfsdk:"echo_ipv4_source"`
+ Ipv6ChecksumDisable types.Bool `tfsdk:"ipv6_checksum_disable"`
+ Disable types.Bool `tfsdk:"disable"`
+ LocalAddress types.String `tfsdk:"local_address"`
+ TxInterval types.Int64 `tfsdk:"tx_interval"`
+ RxInterval types.Int64 `tfsdk:"rx_interval"`
+ Multiplier types.Int64 `tfsdk:"multiplier"`
+}
+
+func (data BFD) getPath() string {
+ return "Cisco-IOS-XR-um-bfd-sbfd-cfg:/bfd"
+}
+
+func (data BFDData) getPath() string {
+ return "Cisco-IOS-XR-um-bfd-sbfd-cfg:/bfd"
+}
+
+func (data BFD) toBody(ctx context.Context) string {
+ body := "{}"
+ if !data.EchoDisable.IsNull() && !data.EchoDisable.IsUnknown() {
+ if data.EchoDisable.ValueBool() {
+ body, _ = sjson.Set(body, "echo.disable", map[string]string{})
+ }
+ }
+ if !data.EchoLatencyDetectPercentage.IsNull() && !data.EchoLatencyDetectPercentage.IsUnknown() {
+ body, _ = sjson.Set(body, "echo.latency.detect.percentage", strconv.FormatInt(data.EchoLatencyDetectPercentage.ValueInt64(), 10))
+ }
+ if !data.EchoLatencyDetectCount.IsNull() && !data.EchoLatencyDetectCount.IsUnknown() {
+ body, _ = sjson.Set(body, "echo.latency.detect.count", strconv.FormatInt(data.EchoLatencyDetectCount.ValueInt64(), 10))
+ }
+ if !data.EchoStartupValidateForce.IsNull() && !data.EchoStartupValidateForce.IsUnknown() {
+ if data.EchoStartupValidateForce.ValueBool() {
+ body, _ = sjson.Set(body, "echo.startup.validate.force", map[string]string{})
+ }
+ }
+ if !data.EchoIpv4Source.IsNull() && !data.EchoIpv4Source.IsUnknown() {
+ body, _ = sjson.Set(body, "echo.ipv4.source", data.EchoIpv4Source.ValueString())
+ }
+ if !data.EchoIpv4BundlePerMemberMinimumIntervalPreferredMinimumInterval.IsNull() && !data.EchoIpv4BundlePerMemberMinimumIntervalPreferredMinimumInterval.IsUnknown() {
+ body, _ = sjson.Set(body, "echo.ipv4.bundle-per-member.minimum-interval.preferred-minimum-interval", strconv.FormatInt(data.EchoIpv4BundlePerMemberMinimumIntervalPreferredMinimumInterval.ValueInt64(), 10))
+ }
+ if !data.TrapSinglehopPreMapped.IsNull() && !data.TrapSinglehopPreMapped.IsUnknown() {
+ if data.TrapSinglehopPreMapped.ValueBool() {
+ body, _ = sjson.Set(body, "trap.singlehop.pre-mapped", map[string]string{})
+ }
+ }
+ if !data.MultihopTtlDropThreshold.IsNull() && !data.MultihopTtlDropThreshold.IsUnknown() {
+ body, _ = sjson.Set(body, "multihop.ttl-drop-threshold", strconv.FormatInt(data.MultihopTtlDropThreshold.ValueInt64(), 10))
+ }
+ if !data.DampeningInitialWait.IsNull() && !data.DampeningInitialWait.IsUnknown() {
+ body, _ = sjson.Set(body, "dampening.initial-wait", strconv.FormatInt(data.DampeningInitialWait.ValueInt64(), 10))
+ }
+ if !data.DampeningSecondaryWait.IsNull() && !data.DampeningSecondaryWait.IsUnknown() {
+ body, _ = sjson.Set(body, "dampening.secondary-wait", strconv.FormatInt(data.DampeningSecondaryWait.ValueInt64(), 10))
+ }
+ if !data.DampeningMaximumWait.IsNull() && !data.DampeningMaximumWait.IsUnknown() {
+ body, _ = sjson.Set(body, "dampening.maximum-wait", strconv.FormatInt(data.DampeningMaximumWait.ValueInt64(), 10))
+ }
+ if !data.DampeningThreshold.IsNull() && !data.DampeningThreshold.IsUnknown() {
+ body, _ = sjson.Set(body, "dampening.threshold", strconv.FormatInt(data.DampeningThreshold.ValueInt64(), 10))
+ }
+ if !data.DampeningExtensionsDownMonitoring.IsNull() && !data.DampeningExtensionsDownMonitoring.IsUnknown() {
+ if data.DampeningExtensionsDownMonitoring.ValueBool() {
+ body, _ = sjson.Set(body, "dampening.extensions.down-monitoring", map[string]string{})
+ }
+ }
+ if !data.DampeningDisable.IsNull() && !data.DampeningDisable.IsUnknown() {
+ if data.DampeningDisable.ValueBool() {
+ body, _ = sjson.Set(body, "dampening.disable", map[string]string{})
+ }
+ }
+ if !data.DampeningBundleMemberL3OnlyMode.IsNull() && !data.DampeningBundleMemberL3OnlyMode.IsUnknown() {
+ if data.DampeningBundleMemberL3OnlyMode.ValueBool() {
+ body, _ = sjson.Set(body, "dampening.bundle-member.l3-only-mode", map[string]string{})
+ }
+ }
+ if !data.DampeningBundleMemberInitialWait.IsNull() && !data.DampeningBundleMemberInitialWait.IsUnknown() {
+ body, _ = sjson.Set(body, "dampening.bundle-member.initial-wait", strconv.FormatInt(data.DampeningBundleMemberInitialWait.ValueInt64(), 10))
+ }
+ if !data.DampeningBundleMemberSecondaryWait.IsNull() && !data.DampeningBundleMemberSecondaryWait.IsUnknown() {
+ body, _ = sjson.Set(body, "dampening.bundle-member.secondary-wait", strconv.FormatInt(data.DampeningBundleMemberSecondaryWait.ValueInt64(), 10))
+ }
+ if !data.DampeningBundleMemberMaximumWait.IsNull() && !data.DampeningBundleMemberMaximumWait.IsUnknown() {
+ body, _ = sjson.Set(body, "dampening.bundle-member.maximum-wait", strconv.FormatInt(data.DampeningBundleMemberMaximumWait.ValueInt64(), 10))
+ }
+ if !data.BundleCoexistenceBobBlbInherit.IsNull() && !data.BundleCoexistenceBobBlbInherit.IsUnknown() {
+ if data.BundleCoexistenceBobBlbInherit.ValueBool() {
+ body, _ = sjson.Set(body, "bundle.coexistence.bob-blb.inherit", map[string]string{})
+ }
+ }
+ if !data.BundleCoexistenceBobBlbLogical.IsNull() && !data.BundleCoexistenceBobBlbLogical.IsUnknown() {
+ if data.BundleCoexistenceBobBlbLogical.ValueBool() {
+ body, _ = sjson.Set(body, "bundle.coexistence.bob-blb.logical", map[string]string{})
+ }
+ }
+ if !data.Ipv6ChecksumDisable.IsNull() && !data.Ipv6ChecksumDisable.IsUnknown() {
+ if data.Ipv6ChecksumDisable.ValueBool() {
+ body, _ = sjson.Set(body, "ipv6.checksum.disable", map[string]string{})
+ }
+ }
+ if len(data.MultipathLocations) > 0 {
+ body, _ = sjson.Set(body, "multipath.include.locations.location", []interface{}{})
+ for index, item := range data.MultipathLocations {
+ if !item.LocationName.IsNull() && !item.LocationName.IsUnknown() {
+ body, _ = sjson.Set(body, "multipath.include.locations.location"+"."+strconv.Itoa(index)+"."+"location-name", item.LocationName.ValueString())
+ }
+ }
+ }
+ if len(data.Interfaces) > 0 {
+ body, _ = sjson.Set(body, "interfaces.interface", []interface{}{})
+ for index, item := range data.Interfaces {
+ if !item.InterfaceName.IsNull() && !item.InterfaceName.IsUnknown() {
+ body, _ = sjson.Set(body, "interfaces.interface"+"."+strconv.Itoa(index)+"."+"interface-name", item.InterfaceName.ValueString())
+ }
+ if !item.EchoDisable.IsNull() && !item.EchoDisable.IsUnknown() {
+ if item.EchoDisable.ValueBool() {
+ body, _ = sjson.Set(body, "interfaces.interface"+"."+strconv.Itoa(index)+"."+"echo.disable", map[string]string{})
+ }
+ }
+ if !item.EchoIpv4Source.IsNull() && !item.EchoIpv4Source.IsUnknown() {
+ body, _ = sjson.Set(body, "interfaces.interface"+"."+strconv.Itoa(index)+"."+"echo.ipv4.source", item.EchoIpv4Source.ValueString())
+ }
+ if !item.Ipv6ChecksumDisable.IsNull() && !item.Ipv6ChecksumDisable.IsUnknown() {
+ if item.Ipv6ChecksumDisable.ValueBool() {
+ body, _ = sjson.Set(body, "interfaces.interface"+"."+strconv.Itoa(index)+"."+"ipv6.checksum.disable", map[string]string{})
+ }
+ }
+ if !item.Disable.IsNull() && !item.Disable.IsUnknown() {
+ if item.Disable.ValueBool() {
+ body, _ = sjson.Set(body, "interfaces.interface"+"."+strconv.Itoa(index)+"."+"disable", map[string]string{})
+ }
+ }
+ if !item.LocalAddress.IsNull() && !item.LocalAddress.IsUnknown() {
+ body, _ = sjson.Set(body, "interfaces.interface"+"."+strconv.Itoa(index)+"."+"local-address", item.LocalAddress.ValueString())
+ }
+ if !item.TxInterval.IsNull() && !item.TxInterval.IsUnknown() {
+ body, _ = sjson.Set(body, "interfaces.interface"+"."+strconv.Itoa(index)+"."+"tx-interval", strconv.FormatInt(item.TxInterval.ValueInt64(), 10))
+ }
+ if !item.RxInterval.IsNull() && !item.RxInterval.IsUnknown() {
+ body, _ = sjson.Set(body, "interfaces.interface"+"."+strconv.Itoa(index)+"."+"rx-interval", strconv.FormatInt(item.RxInterval.ValueInt64(), 10))
+ }
+ if !item.Multiplier.IsNull() && !item.Multiplier.IsUnknown() {
+ body, _ = sjson.Set(body, "interfaces.interface"+"."+strconv.Itoa(index)+"."+"multiplier", strconv.FormatInt(item.Multiplier.ValueInt64(), 10))
+ }
+ }
+ }
+ return body
+}
+
+func (data *BFD) updateFromBody(ctx context.Context, res []byte) {
+ if value := gjson.GetBytes(res, "echo.disable"); !data.EchoDisable.IsNull() {
+ if value.Exists() {
+ data.EchoDisable = types.BoolValue(true)
+ } else {
+ data.EchoDisable = types.BoolValue(false)
+ }
+ } else {
+ data.EchoDisable = types.BoolNull()
+ }
+ if value := gjson.GetBytes(res, "echo.latency.detect.percentage"); value.Exists() && !data.EchoLatencyDetectPercentage.IsNull() {
+ data.EchoLatencyDetectPercentage = types.Int64Value(value.Int())
+ } else {
+ data.EchoLatencyDetectPercentage = types.Int64Null()
+ }
+ if value := gjson.GetBytes(res, "echo.latency.detect.count"); value.Exists() && !data.EchoLatencyDetectCount.IsNull() {
+ data.EchoLatencyDetectCount = types.Int64Value(value.Int())
+ } else {
+ data.EchoLatencyDetectCount = types.Int64Null()
+ }
+ if value := gjson.GetBytes(res, "echo.startup.validate.force"); !data.EchoStartupValidateForce.IsNull() {
+ if value.Exists() {
+ data.EchoStartupValidateForce = types.BoolValue(true)
+ } else {
+ data.EchoStartupValidateForce = types.BoolValue(false)
+ }
+ } else {
+ data.EchoStartupValidateForce = types.BoolNull()
+ }
+ if value := gjson.GetBytes(res, "echo.ipv4.source"); value.Exists() && !data.EchoIpv4Source.IsNull() {
+ data.EchoIpv4Source = types.StringValue(value.String())
+ } else {
+ data.EchoIpv4Source = types.StringNull()
+ }
+ if value := gjson.GetBytes(res, "echo.ipv4.bundle-per-member.minimum-interval.preferred-minimum-interval"); value.Exists() && !data.EchoIpv4BundlePerMemberMinimumIntervalPreferredMinimumInterval.IsNull() {
+ data.EchoIpv4BundlePerMemberMinimumIntervalPreferredMinimumInterval = types.Int64Value(value.Int())
+ } else {
+ data.EchoIpv4BundlePerMemberMinimumIntervalPreferredMinimumInterval = types.Int64Null()
+ }
+ if value := gjson.GetBytes(res, "trap.singlehop.pre-mapped"); !data.TrapSinglehopPreMapped.IsNull() {
+ if value.Exists() {
+ data.TrapSinglehopPreMapped = types.BoolValue(true)
+ } else {
+ data.TrapSinglehopPreMapped = types.BoolValue(false)
+ }
+ } else {
+ data.TrapSinglehopPreMapped = types.BoolNull()
+ }
+ for i := range data.MultipathLocations {
+ keys := [...]string{"location-name"}
+ keyValues := [...]string{data.MultipathLocations[i].LocationName.ValueString()}
+
+ var r gjson.Result
+ gjson.GetBytes(res, "multipath.include.locations.location").ForEach(
+ func(_, v gjson.Result) bool {
+ found := false
+ for ik := range keys {
+ if v.Get(keys[ik]).String() == keyValues[ik] {
+ found = true
+ continue
+ }
+ found = false
+ break
+ }
+ if found {
+ r = v
+ return false
+ }
+ return true
+ },
+ )
+ if value := r.Get("location-name"); value.Exists() && !data.MultipathLocations[i].LocationName.IsNull() {
+ data.MultipathLocations[i].LocationName = types.StringValue(value.String())
+ } else {
+ data.MultipathLocations[i].LocationName = types.StringNull()
+ }
+ }
+ if value := gjson.GetBytes(res, "multihop.ttl-drop-threshold"); value.Exists() && !data.MultihopTtlDropThreshold.IsNull() {
+ data.MultihopTtlDropThreshold = types.Int64Value(value.Int())
+ } else {
+ data.MultihopTtlDropThreshold = types.Int64Null()
+ }
+ if value := gjson.GetBytes(res, "dampening.initial-wait"); value.Exists() && !data.DampeningInitialWait.IsNull() {
+ data.DampeningInitialWait = types.Int64Value(value.Int())
+ } else {
+ data.DampeningInitialWait = types.Int64Null()
+ }
+ if value := gjson.GetBytes(res, "dampening.secondary-wait"); value.Exists() && !data.DampeningSecondaryWait.IsNull() {
+ data.DampeningSecondaryWait = types.Int64Value(value.Int())
+ } else {
+ data.DampeningSecondaryWait = types.Int64Null()
+ }
+ if value := gjson.GetBytes(res, "dampening.maximum-wait"); value.Exists() && !data.DampeningMaximumWait.IsNull() {
+ data.DampeningMaximumWait = types.Int64Value(value.Int())
+ } else {
+ data.DampeningMaximumWait = types.Int64Null()
+ }
+ if value := gjson.GetBytes(res, "dampening.threshold"); value.Exists() && !data.DampeningThreshold.IsNull() {
+ data.DampeningThreshold = types.Int64Value(value.Int())
+ } else {
+ data.DampeningThreshold = types.Int64Null()
+ }
+ if value := gjson.GetBytes(res, "dampening.extensions.down-monitoring"); !data.DampeningExtensionsDownMonitoring.IsNull() {
+ if value.Exists() {
+ data.DampeningExtensionsDownMonitoring = types.BoolValue(true)
+ } else {
+ data.DampeningExtensionsDownMonitoring = types.BoolValue(false)
+ }
+ } else {
+ data.DampeningExtensionsDownMonitoring = types.BoolNull()
+ }
+ if value := gjson.GetBytes(res, "dampening.disable"); !data.DampeningDisable.IsNull() {
+ if value.Exists() {
+ data.DampeningDisable = types.BoolValue(true)
+ } else {
+ data.DampeningDisable = types.BoolValue(false)
+ }
+ } else {
+ data.DampeningDisable = types.BoolNull()
+ }
+ if value := gjson.GetBytes(res, "dampening.bundle-member.l3-only-mode"); !data.DampeningBundleMemberL3OnlyMode.IsNull() {
+ if value.Exists() {
+ data.DampeningBundleMemberL3OnlyMode = types.BoolValue(true)
+ } else {
+ data.DampeningBundleMemberL3OnlyMode = types.BoolValue(false)
+ }
+ } else {
+ data.DampeningBundleMemberL3OnlyMode = types.BoolNull()
+ }
+ if value := gjson.GetBytes(res, "dampening.bundle-member.initial-wait"); value.Exists() && !data.DampeningBundleMemberInitialWait.IsNull() {
+ data.DampeningBundleMemberInitialWait = types.Int64Value(value.Int())
+ } else {
+ data.DampeningBundleMemberInitialWait = types.Int64Null()
+ }
+ if value := gjson.GetBytes(res, "dampening.bundle-member.secondary-wait"); value.Exists() && !data.DampeningBundleMemberSecondaryWait.IsNull() {
+ data.DampeningBundleMemberSecondaryWait = types.Int64Value(value.Int())
+ } else {
+ data.DampeningBundleMemberSecondaryWait = types.Int64Null()
+ }
+ if value := gjson.GetBytes(res, "dampening.bundle-member.maximum-wait"); value.Exists() && !data.DampeningBundleMemberMaximumWait.IsNull() {
+ data.DampeningBundleMemberMaximumWait = types.Int64Value(value.Int())
+ } else {
+ data.DampeningBundleMemberMaximumWait = types.Int64Null()
+ }
+ if value := gjson.GetBytes(res, "bundle.coexistence.bob-blb.inherit"); !data.BundleCoexistenceBobBlbInherit.IsNull() {
+ if value.Exists() {
+ data.BundleCoexistenceBobBlbInherit = types.BoolValue(true)
+ } else {
+ data.BundleCoexistenceBobBlbInherit = types.BoolValue(false)
+ }
+ } else {
+ data.BundleCoexistenceBobBlbInherit = types.BoolNull()
+ }
+ if value := gjson.GetBytes(res, "bundle.coexistence.bob-blb.logical"); !data.BundleCoexistenceBobBlbLogical.IsNull() {
+ if value.Exists() {
+ data.BundleCoexistenceBobBlbLogical = types.BoolValue(true)
+ } else {
+ data.BundleCoexistenceBobBlbLogical = types.BoolValue(false)
+ }
+ } else {
+ data.BundleCoexistenceBobBlbLogical = types.BoolNull()
+ }
+ for i := range data.Interfaces {
+ keys := [...]string{"interface-name"}
+ keyValues := [...]string{data.Interfaces[i].InterfaceName.ValueString()}
+
+ var r gjson.Result
+ gjson.GetBytes(res, "interfaces.interface").ForEach(
+ func(_, v gjson.Result) bool {
+ found := false
+ for ik := range keys {
+ if v.Get(keys[ik]).String() == keyValues[ik] {
+ found = true
+ continue
+ }
+ found = false
+ break
+ }
+ if found {
+ r = v
+ return false
+ }
+ return true
+ },
+ )
+ if value := r.Get("interface-name"); value.Exists() && !data.Interfaces[i].InterfaceName.IsNull() {
+ data.Interfaces[i].InterfaceName = types.StringValue(value.String())
+ } else {
+ data.Interfaces[i].InterfaceName = types.StringNull()
+ }
+ if value := r.Get("echo.disable"); !data.Interfaces[i].EchoDisable.IsNull() {
+ if value.Exists() {
+ data.Interfaces[i].EchoDisable = types.BoolValue(true)
+ } else {
+ data.Interfaces[i].EchoDisable = types.BoolValue(false)
+ }
+ } else {
+ data.Interfaces[i].EchoDisable = types.BoolNull()
+ }
+ if value := r.Get("echo.ipv4.source"); value.Exists() && !data.Interfaces[i].EchoIpv4Source.IsNull() {
+ data.Interfaces[i].EchoIpv4Source = types.StringValue(value.String())
+ } else {
+ data.Interfaces[i].EchoIpv4Source = types.StringNull()
+ }
+ if value := r.Get("ipv6.checksum.disable"); !data.Interfaces[i].Ipv6ChecksumDisable.IsNull() {
+ if value.Exists() {
+ data.Interfaces[i].Ipv6ChecksumDisable = types.BoolValue(true)
+ } else {
+ data.Interfaces[i].Ipv6ChecksumDisable = types.BoolValue(false)
+ }
+ } else {
+ data.Interfaces[i].Ipv6ChecksumDisable = types.BoolNull()
+ }
+ if value := r.Get("disable"); !data.Interfaces[i].Disable.IsNull() {
+ if value.Exists() {
+ data.Interfaces[i].Disable = types.BoolValue(true)
+ } else {
+ data.Interfaces[i].Disable = types.BoolValue(false)
+ }
+ } else {
+ data.Interfaces[i].Disable = types.BoolNull()
+ }
+ if value := r.Get("local-address"); value.Exists() && !data.Interfaces[i].LocalAddress.IsNull() {
+ data.Interfaces[i].LocalAddress = types.StringValue(value.String())
+ } else {
+ data.Interfaces[i].LocalAddress = types.StringNull()
+ }
+ if value := r.Get("tx-interval"); value.Exists() && !data.Interfaces[i].TxInterval.IsNull() {
+ data.Interfaces[i].TxInterval = types.Int64Value(value.Int())
+ } else {
+ data.Interfaces[i].TxInterval = types.Int64Null()
+ }
+ if value := r.Get("rx-interval"); value.Exists() && !data.Interfaces[i].RxInterval.IsNull() {
+ data.Interfaces[i].RxInterval = types.Int64Value(value.Int())
+ } else {
+ data.Interfaces[i].RxInterval = types.Int64Null()
+ }
+ if value := r.Get("multiplier"); value.Exists() && !data.Interfaces[i].Multiplier.IsNull() {
+ data.Interfaces[i].Multiplier = types.Int64Value(value.Int())
+ } else {
+ data.Interfaces[i].Multiplier = types.Int64Null()
+ }
+ }
+ if value := gjson.GetBytes(res, "ipv6.checksum.disable"); !data.Ipv6ChecksumDisable.IsNull() {
+ if value.Exists() {
+ data.Ipv6ChecksumDisable = types.BoolValue(true)
+ } else {
+ data.Ipv6ChecksumDisable = types.BoolValue(false)
+ }
+ } else {
+ data.Ipv6ChecksumDisable = types.BoolNull()
+ }
+}
+
+func (data *BFDData) fromBody(ctx context.Context, res []byte) {
+ if value := gjson.GetBytes(res, "echo.disable"); value.Exists() {
+ data.EchoDisable = types.BoolValue(true)
+ } else {
+ data.EchoDisable = types.BoolValue(false)
+ }
+ if value := gjson.GetBytes(res, "echo.latency.detect.percentage"); value.Exists() {
+ data.EchoLatencyDetectPercentage = types.Int64Value(value.Int())
+ }
+ if value := gjson.GetBytes(res, "echo.latency.detect.count"); value.Exists() {
+ data.EchoLatencyDetectCount = types.Int64Value(value.Int())
+ }
+ if value := gjson.GetBytes(res, "echo.startup.validate.force"); value.Exists() {
+ data.EchoStartupValidateForce = types.BoolValue(true)
+ } else {
+ data.EchoStartupValidateForce = types.BoolValue(false)
+ }
+ if value := gjson.GetBytes(res, "echo.ipv4.source"); value.Exists() {
+ data.EchoIpv4Source = types.StringValue(value.String())
+ }
+ if value := gjson.GetBytes(res, "echo.ipv4.bundle-per-member.minimum-interval.preferred-minimum-interval"); value.Exists() {
+ data.EchoIpv4BundlePerMemberMinimumIntervalPreferredMinimumInterval = types.Int64Value(value.Int())
+ }
+ if value := gjson.GetBytes(res, "trap.singlehop.pre-mapped"); value.Exists() {
+ data.TrapSinglehopPreMapped = types.BoolValue(true)
+ } else {
+ data.TrapSinglehopPreMapped = types.BoolValue(false)
+ }
+ if value := gjson.GetBytes(res, "multipath.include.locations.location"); value.Exists() {
+ data.MultipathLocations = make([]BFDMultipathLocations, 0)
+ value.ForEach(func(k, v gjson.Result) bool {
+ item := BFDMultipathLocations{}
+ if cValue := v.Get("location-name"); cValue.Exists() {
+ item.LocationName = types.StringValue(cValue.String())
+ }
+ data.MultipathLocations = append(data.MultipathLocations, item)
+ return true
+ })
+ }
+ if value := gjson.GetBytes(res, "multihop.ttl-drop-threshold"); value.Exists() {
+ data.MultihopTtlDropThreshold = types.Int64Value(value.Int())
+ }
+ if value := gjson.GetBytes(res, "dampening.initial-wait"); value.Exists() {
+ data.DampeningInitialWait = types.Int64Value(value.Int())
+ }
+ if value := gjson.GetBytes(res, "dampening.secondary-wait"); value.Exists() {
+ data.DampeningSecondaryWait = types.Int64Value(value.Int())
+ }
+ if value := gjson.GetBytes(res, "dampening.maximum-wait"); value.Exists() {
+ data.DampeningMaximumWait = types.Int64Value(value.Int())
+ }
+ if value := gjson.GetBytes(res, "dampening.threshold"); value.Exists() {
+ data.DampeningThreshold = types.Int64Value(value.Int())
+ }
+ if value := gjson.GetBytes(res, "dampening.extensions.down-monitoring"); value.Exists() {
+ data.DampeningExtensionsDownMonitoring = types.BoolValue(true)
+ } else {
+ data.DampeningExtensionsDownMonitoring = types.BoolValue(false)
+ }
+ if value := gjson.GetBytes(res, "dampening.disable"); value.Exists() {
+ data.DampeningDisable = types.BoolValue(true)
+ } else {
+ data.DampeningDisable = types.BoolValue(false)
+ }
+ if value := gjson.GetBytes(res, "dampening.bundle-member.l3-only-mode"); value.Exists() {
+ data.DampeningBundleMemberL3OnlyMode = types.BoolValue(true)
+ } else {
+ data.DampeningBundleMemberL3OnlyMode = types.BoolValue(false)
+ }
+ if value := gjson.GetBytes(res, "dampening.bundle-member.initial-wait"); value.Exists() {
+ data.DampeningBundleMemberInitialWait = types.Int64Value(value.Int())
+ }
+ if value := gjson.GetBytes(res, "dampening.bundle-member.secondary-wait"); value.Exists() {
+ data.DampeningBundleMemberSecondaryWait = types.Int64Value(value.Int())
+ }
+ if value := gjson.GetBytes(res, "dampening.bundle-member.maximum-wait"); value.Exists() {
+ data.DampeningBundleMemberMaximumWait = types.Int64Value(value.Int())
+ }
+ if value := gjson.GetBytes(res, "bundle.coexistence.bob-blb.inherit"); value.Exists() {
+ data.BundleCoexistenceBobBlbInherit = types.BoolValue(true)
+ } else {
+ data.BundleCoexistenceBobBlbInherit = types.BoolValue(false)
+ }
+ if value := gjson.GetBytes(res, "bundle.coexistence.bob-blb.logical"); value.Exists() {
+ data.BundleCoexistenceBobBlbLogical = types.BoolValue(true)
+ } else {
+ data.BundleCoexistenceBobBlbLogical = types.BoolValue(false)
+ }
+ if value := gjson.GetBytes(res, "interfaces.interface"); value.Exists() {
+ data.Interfaces = make([]BFDInterfaces, 0)
+ value.ForEach(func(k, v gjson.Result) bool {
+ item := BFDInterfaces{}
+ if cValue := v.Get("interface-name"); cValue.Exists() {
+ item.InterfaceName = types.StringValue(cValue.String())
+ }
+ if cValue := v.Get("echo.disable"); cValue.Exists() {
+ item.EchoDisable = types.BoolValue(true)
+ } else {
+ item.EchoDisable = types.BoolValue(false)
+ }
+ if cValue := v.Get("echo.ipv4.source"); cValue.Exists() {
+ item.EchoIpv4Source = types.StringValue(cValue.String())
+ }
+ if cValue := v.Get("ipv6.checksum.disable"); cValue.Exists() {
+ item.Ipv6ChecksumDisable = types.BoolValue(true)
+ } else {
+ item.Ipv6ChecksumDisable = types.BoolValue(false)
+ }
+ if cValue := v.Get("disable"); cValue.Exists() {
+ item.Disable = types.BoolValue(true)
+ } else {
+ item.Disable = types.BoolValue(false)
+ }
+ if cValue := v.Get("local-address"); cValue.Exists() {
+ item.LocalAddress = types.StringValue(cValue.String())
+ }
+ if cValue := v.Get("tx-interval"); cValue.Exists() {
+ item.TxInterval = types.Int64Value(cValue.Int())
+ }
+ if cValue := v.Get("rx-interval"); cValue.Exists() {
+ item.RxInterval = types.Int64Value(cValue.Int())
+ }
+ if cValue := v.Get("multiplier"); cValue.Exists() {
+ item.Multiplier = types.Int64Value(cValue.Int())
+ }
+ data.Interfaces = append(data.Interfaces, item)
+ return true
+ })
+ }
+ if value := gjson.GetBytes(res, "ipv6.checksum.disable"); value.Exists() {
+ data.Ipv6ChecksumDisable = types.BoolValue(true)
+ } else {
+ data.Ipv6ChecksumDisable = types.BoolValue(false)
+ }
+}
+
+func (data *BFD) getDeletedListItems(ctx context.Context, state BFD) []string {
+ deletedListItems := make([]string, 0)
+ for i := range state.MultipathLocations {
+ keys := [...]string{"location-name"}
+ stateKeyValues := [...]string{state.MultipathLocations[i].LocationName.ValueString()}
+
+ emptyKeys := true
+ if !reflect.ValueOf(state.MultipathLocations[i].LocationName.ValueString()).IsZero() {
+ emptyKeys = false
+ }
+ if emptyKeys {
+ continue
+ }
+
+ found := false
+ for j := range data.MultipathLocations {
+ found = true
+ if state.MultipathLocations[i].LocationName.ValueString() != data.MultipathLocations[j].LocationName.ValueString() {
+ found = false
+ }
+ if found {
+ break
+ }
+ }
+ if !found {
+ keyString := ""
+ for ki := range keys {
+ keyString += "[" + keys[ki] + "=" + stateKeyValues[ki] + "]"
+ }
+ deletedListItems = append(deletedListItems, fmt.Sprintf("%v/multipath/include/locations/location%v", state.getPath(), keyString))
+ }
+ }
+ for i := range state.Interfaces {
+ keys := [...]string{"interface-name"}
+ stateKeyValues := [...]string{state.Interfaces[i].InterfaceName.ValueString()}
+
+ emptyKeys := true
+ if !reflect.ValueOf(state.Interfaces[i].InterfaceName.ValueString()).IsZero() {
+ emptyKeys = false
+ }
+ if emptyKeys {
+ continue
+ }
+
+ found := false
+ for j := range data.Interfaces {
+ found = true
+ if state.Interfaces[i].InterfaceName.ValueString() != data.Interfaces[j].InterfaceName.ValueString() {
+ found = false
+ }
+ if found {
+ break
+ }
+ }
+ if !found {
+ keyString := ""
+ for ki := range keys {
+ keyString += "[" + keys[ki] + "=" + stateKeyValues[ki] + "]"
+ }
+ deletedListItems = append(deletedListItems, fmt.Sprintf("%v/interfaces/interface%v", state.getPath(), keyString))
+ }
+ }
+ return deletedListItems
+}
+
+func (data *BFD) getEmptyLeafsDelete(ctx context.Context) []string {
+ emptyLeafsDelete := make([]string, 0)
+ if !data.EchoDisable.IsNull() && !data.EchoDisable.ValueBool() {
+ emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/echo/disable", data.getPath()))
+ }
+ if !data.EchoStartupValidateForce.IsNull() && !data.EchoStartupValidateForce.ValueBool() {
+ emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/echo/startup/validate/force", data.getPath()))
+ }
+ if !data.TrapSinglehopPreMapped.IsNull() && !data.TrapSinglehopPreMapped.ValueBool() {
+ emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/trap/singlehop/pre-mapped", data.getPath()))
+ }
+ for i := range data.MultipathLocations {
+ keys := [...]string{"location-name"}
+ keyValues := [...]string{data.MultipathLocations[i].LocationName.ValueString()}
+ keyString := ""
+ for ki := range keys {
+ keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]"
+ }
+ }
+ if !data.DampeningExtensionsDownMonitoring.IsNull() && !data.DampeningExtensionsDownMonitoring.ValueBool() {
+ emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/dampening/extensions/down-monitoring", data.getPath()))
+ }
+ if !data.DampeningDisable.IsNull() && !data.DampeningDisable.ValueBool() {
+ emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/dampening/disable", data.getPath()))
+ }
+ if !data.DampeningBundleMemberL3OnlyMode.IsNull() && !data.DampeningBundleMemberL3OnlyMode.ValueBool() {
+ emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/dampening/bundle-member/l3-only-mode", data.getPath()))
+ }
+ if !data.BundleCoexistenceBobBlbInherit.IsNull() && !data.BundleCoexistenceBobBlbInherit.ValueBool() {
+ emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/bundle/coexistence/bob-blb/inherit", data.getPath()))
+ }
+ if !data.BundleCoexistenceBobBlbLogical.IsNull() && !data.BundleCoexistenceBobBlbLogical.ValueBool() {
+ emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/bundle/coexistence/bob-blb/logical", data.getPath()))
+ }
+ for i := range data.Interfaces {
+ keys := [...]string{"interface-name"}
+ keyValues := [...]string{data.Interfaces[i].InterfaceName.ValueString()}
+ keyString := ""
+ for ki := range keys {
+ keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]"
+ }
+ if !data.Interfaces[i].EchoDisable.IsNull() && !data.Interfaces[i].EchoDisable.ValueBool() {
+ emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/interfaces/interface%v/echo/disable", data.getPath(), keyString))
+ }
+ if !data.Interfaces[i].Ipv6ChecksumDisable.IsNull() && !data.Interfaces[i].Ipv6ChecksumDisable.ValueBool() {
+ emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/interfaces/interface%v/ipv6/checksum/disable", data.getPath(), keyString))
+ }
+ if !data.Interfaces[i].Disable.IsNull() && !data.Interfaces[i].Disable.ValueBool() {
+ emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/interfaces/interface%v/disable", data.getPath(), keyString))
+ }
+ }
+ if !data.Ipv6ChecksumDisable.IsNull() && !data.Ipv6ChecksumDisable.ValueBool() {
+ emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/ipv6/checksum/disable", data.getPath()))
+ }
+ return emptyLeafsDelete
+}
+
+func (data *BFD) getDeletePaths(ctx context.Context) []string {
+ var deletePaths []string
+ if !data.EchoDisable.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/echo/disable", data.getPath()))
+ }
+ if !data.EchoLatencyDetectPercentage.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/echo/latency/detect/percentage", data.getPath()))
+ }
+ if !data.EchoLatencyDetectCount.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/echo/latency/detect/count", data.getPath()))
+ }
+ if !data.EchoStartupValidateForce.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/echo/startup/validate/force", data.getPath()))
+ }
+ if !data.EchoIpv4Source.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/echo/ipv4/source", data.getPath()))
+ }
+ if !data.EchoIpv4BundlePerMemberMinimumIntervalPreferredMinimumInterval.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/echo/ipv4/bundle-per-member/minimum-interval/preferred-minimum-interval", data.getPath()))
+ }
+ if !data.TrapSinglehopPreMapped.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/trap/singlehop/pre-mapped", data.getPath()))
+ }
+ for i := range data.MultipathLocations {
+ keys := [...]string{"location-name"}
+ keyValues := [...]string{data.MultipathLocations[i].LocationName.ValueString()}
+
+ keyString := ""
+ for ki := range keys {
+ keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]"
+ }
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/multipath/include/locations/location%v", data.getPath(), keyString))
+ }
+ if !data.MultihopTtlDropThreshold.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/multihop/ttl-drop-threshold", data.getPath()))
+ }
+ if !data.DampeningInitialWait.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/dampening/initial-wait", data.getPath()))
+ }
+ if !data.DampeningSecondaryWait.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/dampening/secondary-wait", data.getPath()))
+ }
+ if !data.DampeningMaximumWait.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/dampening/maximum-wait", data.getPath()))
+ }
+ if !data.DampeningThreshold.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/dampening/threshold", data.getPath()))
+ }
+ if !data.DampeningExtensionsDownMonitoring.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/dampening/extensions/down-monitoring", data.getPath()))
+ }
+ if !data.DampeningDisable.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/dampening/disable", data.getPath()))
+ }
+ if !data.DampeningBundleMemberL3OnlyMode.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/dampening/bundle-member/l3-only-mode", data.getPath()))
+ }
+ if !data.DampeningBundleMemberInitialWait.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/dampening/bundle-member/initial-wait", data.getPath()))
+ }
+ if !data.DampeningBundleMemberSecondaryWait.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/dampening/bundle-member/secondary-wait", data.getPath()))
+ }
+ if !data.DampeningBundleMemberMaximumWait.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/dampening/bundle-member/maximum-wait", data.getPath()))
+ }
+ if !data.BundleCoexistenceBobBlbInherit.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/bundle/coexistence/bob-blb/inherit", data.getPath()))
+ }
+ if !data.BundleCoexistenceBobBlbLogical.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/bundle/coexistence/bob-blb/logical", data.getPath()))
+ }
+ for i := range data.Interfaces {
+ keys := [...]string{"interface-name"}
+ keyValues := [...]string{data.Interfaces[i].InterfaceName.ValueString()}
+
+ keyString := ""
+ for ki := range keys {
+ keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]"
+ }
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/interfaces/interface%v", data.getPath(), keyString))
+ }
+ if !data.Ipv6ChecksumDisable.IsNull() {
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/ipv6/checksum/disable", data.getPath()))
+ }
+ return deletePaths
+}
diff --git a/internal/provider/model_iosxr_flow_exporter_map.go b/internal/provider/model_iosxr_flow_exporter_map.go
new file mode 100644
index 00000000..1afe9cca
--- /dev/null
+++ b/internal/provider/model_iosxr_flow_exporter_map.go
@@ -0,0 +1,379 @@
+// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+// Code generated by "gen/generator.go"; DO NOT EDIT.
+
+package provider
+
+import (
+ "context"
+ "fmt"
+ "reflect"
+ "strconv"
+
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/tidwall/gjson"
+ "github.com/tidwall/sjson"
+)
+
+type FlowExporterMap struct {
+ Device types.String `tfsdk:"device"`
+ Id types.String `tfsdk:"id"`
+ ExporterMaps []FlowExporterMapExporterMaps `tfsdk:"exporter_maps"`
+}
+
+type FlowExporterMapData struct {
+ Device types.String `tfsdk:"device"`
+ Id types.String `tfsdk:"id"`
+ ExporterMaps []FlowExporterMapExporterMaps `tfsdk:"exporter_maps"`
+}
+type FlowExporterMapExporterMaps struct {
+ ExporterMapName types.String `tfsdk:"exporter_map_name"`
+ DestinationIpv4Address types.String `tfsdk:"destination_ipv4_address"`
+ DestinationIpv6Address types.String `tfsdk:"destination_ipv6_address"`
+ DestinationVrf types.String `tfsdk:"destination_vrf"`
+ Source types.String `tfsdk:"source"`
+ Dscp types.Int64 `tfsdk:"dscp"`
+ PacketLength types.Int64 `tfsdk:"packet_length"`
+ TransportUdp types.Int64 `tfsdk:"transport_udp"`
+ DfbitSet types.Bool `tfsdk:"dfbit_set"`
+ VersionExportFormat types.String `tfsdk:"version_export_format"`
+ VersionTemplateDataTimeout types.Int64 `tfsdk:"version_template_data_timeout"`
+ VersionTemplateOptionsTimeout types.Int64 `tfsdk:"version_template_options_timeout"`
+ VersionTemplateTimeout types.Int64 `tfsdk:"version_template_timeout"`
+ VersionOptionsInterfaceTableTimeout types.Int64 `tfsdk:"version_options_interface_table_timeout"`
+ VersionOptionsSamplerTableTimeout types.Int64 `tfsdk:"version_options_sampler_table_timeout"`
+ VersionOptionsClassTableTimeout types.Int64 `tfsdk:"version_options_class_table_timeout"`
+ VersionOptionsVrfTableTimeout types.Int64 `tfsdk:"version_options_vrf_table_timeout"`
+}
+
+func (data FlowExporterMap) getPath() string {
+ return "Cisco-IOS-XR-um-flow-cfg:/flow/exporter-maps"
+}
+
+func (data FlowExporterMapData) getPath() string {
+ return "Cisco-IOS-XR-um-flow-cfg:/flow/exporter-maps"
+}
+
+func (data FlowExporterMap) toBody(ctx context.Context) string {
+ body := "{}"
+ if len(data.ExporterMaps) > 0 {
+ body, _ = sjson.Set(body, "exporter-map", []interface{}{})
+ for index, item := range data.ExporterMaps {
+ if !item.ExporterMapName.IsNull() && !item.ExporterMapName.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"exporter-map-name", item.ExporterMapName.ValueString())
+ }
+ if !item.DestinationIpv4Address.IsNull() && !item.DestinationIpv4Address.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"destination.ipv4-address", item.DestinationIpv4Address.ValueString())
+ }
+ if !item.DestinationIpv6Address.IsNull() && !item.DestinationIpv6Address.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"destination.ipv6-address", item.DestinationIpv6Address.ValueString())
+ }
+ if !item.DestinationVrf.IsNull() && !item.DestinationVrf.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"destination.vrf", item.DestinationVrf.ValueString())
+ }
+ if !item.Source.IsNull() && !item.Source.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"source", item.Source.ValueString())
+ }
+ if !item.Dscp.IsNull() && !item.Dscp.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"dscp", strconv.FormatInt(item.Dscp.ValueInt64(), 10))
+ }
+ if !item.PacketLength.IsNull() && !item.PacketLength.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"packet-length", strconv.FormatInt(item.PacketLength.ValueInt64(), 10))
+ }
+ if !item.TransportUdp.IsNull() && !item.TransportUdp.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"transport.udp", strconv.FormatInt(item.TransportUdp.ValueInt64(), 10))
+ }
+ if !item.DfbitSet.IsNull() && !item.DfbitSet.IsUnknown() {
+ if item.DfbitSet.ValueBool() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"dfbit.set", map[string]string{})
+ }
+ }
+ if !item.VersionExportFormat.IsNull() && !item.VersionExportFormat.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"version.export-format", item.VersionExportFormat.ValueString())
+ }
+ if !item.VersionTemplateDataTimeout.IsNull() && !item.VersionTemplateDataTimeout.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"version.template.data.timeout", strconv.FormatInt(item.VersionTemplateDataTimeout.ValueInt64(), 10))
+ }
+ if !item.VersionTemplateOptionsTimeout.IsNull() && !item.VersionTemplateOptionsTimeout.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"version.template.options.timeout", strconv.FormatInt(item.VersionTemplateOptionsTimeout.ValueInt64(), 10))
+ }
+ if !item.VersionTemplateTimeout.IsNull() && !item.VersionTemplateTimeout.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"version.template.timeout", strconv.FormatInt(item.VersionTemplateTimeout.ValueInt64(), 10))
+ }
+ if !item.VersionOptionsInterfaceTableTimeout.IsNull() && !item.VersionOptionsInterfaceTableTimeout.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"version.options.interface-table.timeout", strconv.FormatInt(item.VersionOptionsInterfaceTableTimeout.ValueInt64(), 10))
+ }
+ if !item.VersionOptionsSamplerTableTimeout.IsNull() && !item.VersionOptionsSamplerTableTimeout.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"version.options.sampler-table.timeout", strconv.FormatInt(item.VersionOptionsSamplerTableTimeout.ValueInt64(), 10))
+ }
+ if !item.VersionOptionsClassTableTimeout.IsNull() && !item.VersionOptionsClassTableTimeout.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"version.options.class-table.timeout", strconv.FormatInt(item.VersionOptionsClassTableTimeout.ValueInt64(), 10))
+ }
+ if !item.VersionOptionsVrfTableTimeout.IsNull() && !item.VersionOptionsVrfTableTimeout.IsUnknown() {
+ body, _ = sjson.Set(body, "exporter-map"+"."+strconv.Itoa(index)+"."+"version.options.vrf-table.timeout", strconv.FormatInt(item.VersionOptionsVrfTableTimeout.ValueInt64(), 10))
+ }
+ }
+ }
+ return body
+}
+
+func (data *FlowExporterMap) updateFromBody(ctx context.Context, res []byte) {
+ for i := range data.ExporterMaps {
+ keys := [...]string{"exporter-map-name"}
+ keyValues := [...]string{data.ExporterMaps[i].ExporterMapName.ValueString()}
+
+ var r gjson.Result
+ gjson.GetBytes(res, "exporter-map").ForEach(
+ func(_, v gjson.Result) bool {
+ found := false
+ for ik := range keys {
+ if v.Get(keys[ik]).String() == keyValues[ik] {
+ found = true
+ continue
+ }
+ found = false
+ break
+ }
+ if found {
+ r = v
+ return false
+ }
+ return true
+ },
+ )
+ if value := r.Get("exporter-map-name"); value.Exists() && !data.ExporterMaps[i].ExporterMapName.IsNull() {
+ data.ExporterMaps[i].ExporterMapName = types.StringValue(value.String())
+ } else {
+ data.ExporterMaps[i].ExporterMapName = types.StringNull()
+ }
+ if value := r.Get("destination.ipv4-address"); value.Exists() && !data.ExporterMaps[i].DestinationIpv4Address.IsNull() {
+ data.ExporterMaps[i].DestinationIpv4Address = types.StringValue(value.String())
+ } else {
+ data.ExporterMaps[i].DestinationIpv4Address = types.StringNull()
+ }
+ if value := r.Get("destination.ipv6-address"); value.Exists() && !data.ExporterMaps[i].DestinationIpv6Address.IsNull() {
+ data.ExporterMaps[i].DestinationIpv6Address = types.StringValue(value.String())
+ } else {
+ data.ExporterMaps[i].DestinationIpv6Address = types.StringNull()
+ }
+ if value := r.Get("destination.vrf"); value.Exists() && !data.ExporterMaps[i].DestinationVrf.IsNull() {
+ data.ExporterMaps[i].DestinationVrf = types.StringValue(value.String())
+ } else {
+ data.ExporterMaps[i].DestinationVrf = types.StringNull()
+ }
+ if value := r.Get("source"); value.Exists() && !data.ExporterMaps[i].Source.IsNull() {
+ data.ExporterMaps[i].Source = types.StringValue(value.String())
+ } else {
+ data.ExporterMaps[i].Source = types.StringNull()
+ }
+ if value := r.Get("dscp"); value.Exists() && !data.ExporterMaps[i].Dscp.IsNull() {
+ data.ExporterMaps[i].Dscp = types.Int64Value(value.Int())
+ } else {
+ data.ExporterMaps[i].Dscp = types.Int64Null()
+ }
+ if value := r.Get("packet-length"); value.Exists() && !data.ExporterMaps[i].PacketLength.IsNull() {
+ data.ExporterMaps[i].PacketLength = types.Int64Value(value.Int())
+ } else {
+ data.ExporterMaps[i].PacketLength = types.Int64Null()
+ }
+ if value := r.Get("transport.udp"); value.Exists() && !data.ExporterMaps[i].TransportUdp.IsNull() {
+ data.ExporterMaps[i].TransportUdp = types.Int64Value(value.Int())
+ } else {
+ data.ExporterMaps[i].TransportUdp = types.Int64Null()
+ }
+ if value := r.Get("dfbit.set"); !data.ExporterMaps[i].DfbitSet.IsNull() {
+ if value.Exists() {
+ data.ExporterMaps[i].DfbitSet = types.BoolValue(true)
+ } else {
+ data.ExporterMaps[i].DfbitSet = types.BoolValue(false)
+ }
+ } else {
+ data.ExporterMaps[i].DfbitSet = types.BoolNull()
+ }
+ if value := r.Get("version.export-format"); value.Exists() && !data.ExporterMaps[i].VersionExportFormat.IsNull() {
+ data.ExporterMaps[i].VersionExportFormat = types.StringValue(value.String())
+ } else {
+ data.ExporterMaps[i].VersionExportFormat = types.StringNull()
+ }
+ if value := r.Get("version.template.data.timeout"); value.Exists() && !data.ExporterMaps[i].VersionTemplateDataTimeout.IsNull() {
+ data.ExporterMaps[i].VersionTemplateDataTimeout = types.Int64Value(value.Int())
+ } else {
+ data.ExporterMaps[i].VersionTemplateDataTimeout = types.Int64Null()
+ }
+ if value := r.Get("version.template.options.timeout"); value.Exists() && !data.ExporterMaps[i].VersionTemplateOptionsTimeout.IsNull() {
+ data.ExporterMaps[i].VersionTemplateOptionsTimeout = types.Int64Value(value.Int())
+ } else {
+ data.ExporterMaps[i].VersionTemplateOptionsTimeout = types.Int64Null()
+ }
+ if value := r.Get("version.template.timeout"); value.Exists() && !data.ExporterMaps[i].VersionTemplateTimeout.IsNull() {
+ data.ExporterMaps[i].VersionTemplateTimeout = types.Int64Value(value.Int())
+ } else {
+ data.ExporterMaps[i].VersionTemplateTimeout = types.Int64Null()
+ }
+ if value := r.Get("version.options.interface-table.timeout"); value.Exists() && !data.ExporterMaps[i].VersionOptionsInterfaceTableTimeout.IsNull() {
+ data.ExporterMaps[i].VersionOptionsInterfaceTableTimeout = types.Int64Value(value.Int())
+ } else {
+ data.ExporterMaps[i].VersionOptionsInterfaceTableTimeout = types.Int64Null()
+ }
+ if value := r.Get("version.options.sampler-table.timeout"); value.Exists() && !data.ExporterMaps[i].VersionOptionsSamplerTableTimeout.IsNull() {
+ data.ExporterMaps[i].VersionOptionsSamplerTableTimeout = types.Int64Value(value.Int())
+ } else {
+ data.ExporterMaps[i].VersionOptionsSamplerTableTimeout = types.Int64Null()
+ }
+ if value := r.Get("version.options.class-table.timeout"); value.Exists() && !data.ExporterMaps[i].VersionOptionsClassTableTimeout.IsNull() {
+ data.ExporterMaps[i].VersionOptionsClassTableTimeout = types.Int64Value(value.Int())
+ } else {
+ data.ExporterMaps[i].VersionOptionsClassTableTimeout = types.Int64Null()
+ }
+ if value := r.Get("version.options.vrf-table.timeout"); value.Exists() && !data.ExporterMaps[i].VersionOptionsVrfTableTimeout.IsNull() {
+ data.ExporterMaps[i].VersionOptionsVrfTableTimeout = types.Int64Value(value.Int())
+ } else {
+ data.ExporterMaps[i].VersionOptionsVrfTableTimeout = types.Int64Null()
+ }
+ }
+}
+
+func (data *FlowExporterMapData) fromBody(ctx context.Context, res []byte) {
+ if value := gjson.GetBytes(res, "exporter-map"); value.Exists() {
+ data.ExporterMaps = make([]FlowExporterMapExporterMaps, 0)
+ value.ForEach(func(k, v gjson.Result) bool {
+ item := FlowExporterMapExporterMaps{}
+ if cValue := v.Get("exporter-map-name"); cValue.Exists() {
+ item.ExporterMapName = types.StringValue(cValue.String())
+ }
+ if cValue := v.Get("destination.ipv4-address"); cValue.Exists() {
+ item.DestinationIpv4Address = types.StringValue(cValue.String())
+ }
+ if cValue := v.Get("destination.ipv6-address"); cValue.Exists() {
+ item.DestinationIpv6Address = types.StringValue(cValue.String())
+ }
+ if cValue := v.Get("destination.vrf"); cValue.Exists() {
+ item.DestinationVrf = types.StringValue(cValue.String())
+ }
+ if cValue := v.Get("source"); cValue.Exists() {
+ item.Source = types.StringValue(cValue.String())
+ }
+ if cValue := v.Get("dscp"); cValue.Exists() {
+ item.Dscp = types.Int64Value(cValue.Int())
+ }
+ if cValue := v.Get("packet-length"); cValue.Exists() {
+ item.PacketLength = types.Int64Value(cValue.Int())
+ }
+ if cValue := v.Get("transport.udp"); cValue.Exists() {
+ item.TransportUdp = types.Int64Value(cValue.Int())
+ }
+ if cValue := v.Get("dfbit.set"); cValue.Exists() {
+ item.DfbitSet = types.BoolValue(true)
+ } else {
+ item.DfbitSet = types.BoolValue(false)
+ }
+ if cValue := v.Get("version.export-format"); cValue.Exists() {
+ item.VersionExportFormat = types.StringValue(cValue.String())
+ }
+ if cValue := v.Get("version.template.data.timeout"); cValue.Exists() {
+ item.VersionTemplateDataTimeout = types.Int64Value(cValue.Int())
+ }
+ if cValue := v.Get("version.template.options.timeout"); cValue.Exists() {
+ item.VersionTemplateOptionsTimeout = types.Int64Value(cValue.Int())
+ }
+ if cValue := v.Get("version.template.timeout"); cValue.Exists() {
+ item.VersionTemplateTimeout = types.Int64Value(cValue.Int())
+ }
+ if cValue := v.Get("version.options.interface-table.timeout"); cValue.Exists() {
+ item.VersionOptionsInterfaceTableTimeout = types.Int64Value(cValue.Int())
+ }
+ if cValue := v.Get("version.options.sampler-table.timeout"); cValue.Exists() {
+ item.VersionOptionsSamplerTableTimeout = types.Int64Value(cValue.Int())
+ }
+ if cValue := v.Get("version.options.class-table.timeout"); cValue.Exists() {
+ item.VersionOptionsClassTableTimeout = types.Int64Value(cValue.Int())
+ }
+ if cValue := v.Get("version.options.vrf-table.timeout"); cValue.Exists() {
+ item.VersionOptionsVrfTableTimeout = types.Int64Value(cValue.Int())
+ }
+ data.ExporterMaps = append(data.ExporterMaps, item)
+ return true
+ })
+ }
+}
+
+func (data *FlowExporterMap) getDeletedListItems(ctx context.Context, state FlowExporterMap) []string {
+ deletedListItems := make([]string, 0)
+ for i := range state.ExporterMaps {
+ keys := [...]string{"exporter-map-name"}
+ stateKeyValues := [...]string{state.ExporterMaps[i].ExporterMapName.ValueString()}
+
+ emptyKeys := true
+ if !reflect.ValueOf(state.ExporterMaps[i].ExporterMapName.ValueString()).IsZero() {
+ emptyKeys = false
+ }
+ if emptyKeys {
+ continue
+ }
+
+ found := false
+ for j := range data.ExporterMaps {
+ found = true
+ if state.ExporterMaps[i].ExporterMapName.ValueString() != data.ExporterMaps[j].ExporterMapName.ValueString() {
+ found = false
+ }
+ if found {
+ break
+ }
+ }
+ if !found {
+ keyString := ""
+ for ki := range keys {
+ keyString += "[" + keys[ki] + "=" + stateKeyValues[ki] + "]"
+ }
+ deletedListItems = append(deletedListItems, fmt.Sprintf("%v/exporter-map%v", state.getPath(), keyString))
+ }
+ }
+ return deletedListItems
+}
+
+func (data *FlowExporterMap) getEmptyLeafsDelete(ctx context.Context) []string {
+ emptyLeafsDelete := make([]string, 0)
+ for i := range data.ExporterMaps {
+ keys := [...]string{"exporter-map-name"}
+ keyValues := [...]string{data.ExporterMaps[i].ExporterMapName.ValueString()}
+ keyString := ""
+ for ki := range keys {
+ keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]"
+ }
+ if !data.ExporterMaps[i].DfbitSet.IsNull() && !data.ExporterMaps[i].DfbitSet.ValueBool() {
+ emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/exporter-map%v/dfbit/set", data.getPath(), keyString))
+ }
+ }
+ return emptyLeafsDelete
+}
+
+func (data *FlowExporterMap) getDeletePaths(ctx context.Context) []string {
+ var deletePaths []string
+ for i := range data.ExporterMaps {
+ keys := [...]string{"exporter-map-name"}
+ keyValues := [...]string{data.ExporterMaps[i].ExporterMapName.ValueString()}
+
+ keyString := ""
+ for ki := range keys {
+ keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]"
+ }
+ deletePaths = append(deletePaths, fmt.Sprintf("%v/exporter-map%v", data.getPath(), keyString))
+ }
+ return deletePaths
+}
diff --git a/internal/provider/provider.go b/internal/provider/provider.go
index 1441209c..389fbc68 100644
--- a/internal/provider/provider.go
+++ b/internal/provider/provider.go
@@ -318,6 +318,7 @@ func (p *iosxrProvider) Resources(ctx context.Context) []func() resource.Resourc
NewGnmiResource,
NewASPathSetResource,
NewBannerResource,
+ NewBFDResource,
NewBGPASFormatResource,
NewCDPResource,
NewClassMapQoSResource,
@@ -335,6 +336,7 @@ func (p *iosxrProvider) Resources(ctx context.Context) []func() resource.Resourc
NewExtcommunityOpaqueSetResource,
NewExtcommunityRTSetResource,
NewExtcommunitySOOSetResource,
+ NewFlowExporterMapResource,
NewFlowMonitorMapResource,
NewFlowSamplerMapResource,
NewFPDResource,
@@ -409,6 +411,7 @@ func (p *iosxrProvider) DataSources(ctx context.Context) []func() datasource.Dat
NewGnmiDataSource,
NewASPathSetDataSource,
NewBannerDataSource,
+ NewBFDDataSource,
NewBGPASFormatDataSource,
NewCDPDataSource,
NewClassMapQoSDataSource,
@@ -426,6 +429,7 @@ func (p *iosxrProvider) DataSources(ctx context.Context) []func() datasource.Dat
NewExtcommunityOpaqueSetDataSource,
NewExtcommunityRTSetDataSource,
NewExtcommunitySOOSetDataSource,
+ NewFlowExporterMapDataSource,
NewFlowMonitorMapDataSource,
NewFlowSamplerMapDataSource,
NewFPDDataSource,
diff --git a/internal/provider/resource_iosxr_bfd.go b/internal/provider/resource_iosxr_bfd.go
new file mode 100644
index 00000000..2a73c473
--- /dev/null
+++ b/internal/provider/resource_iosxr_bfd.go
@@ -0,0 +1,444 @@
+// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+// Code generated by "gen/generator.go"; DO NOT EDIT.
+
+package provider
+
+import (
+ "context"
+ "fmt"
+ "regexp"
+
+ "github.com/CiscoDevNet/terraform-provider-iosxr/internal/provider/client"
+ "github.com/CiscoDevNet/terraform-provider-iosxr/internal/provider/helpers"
+ "github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/resource"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
+)
+
+func NewBFDResource() resource.Resource {
+ return &BFDResource{}
+}
+
+type BFDResource struct {
+ client *client.Client
+}
+
+func (r *BFDResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_bfd"
+}
+
+func (r *BFDResource) 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: "This resource can manage the BFD configuration.",
+
+ Attributes: map[string]schema.Attribute{
+ "device": schema.StringAttribute{
+ MarkdownDescription: "A device name from the provider configuration.",
+ Optional: true,
+ },
+ "id": schema.StringAttribute{
+ MarkdownDescription: "The path of the object.",
+ Computed: true,
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.UseStateForUnknown(),
+ },
+ },
+ "delete_mode": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Configure behavior when deleting/destroying the resource. Either delete the entire object (YANG container) being managed, or only delete the individual resource attributes configured explicitly and leave everything else as-is. Default value is `all`.").AddStringEnumDescription("all", "attributes").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf("all", "attributes"),
+ },
+ },
+ "echo_disable": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Disable BFD echo mode").String,
+ Optional: true,
+ },
+ "echo_latency_detect_percentage": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Percentage of detection time to consider as bad latency").AddIntegerRangeDescription(100, 250).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(100, 250),
+ },
+ },
+ "echo_latency_detect_count": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Count of consecutive bad latency packets to take session down").AddIntegerRangeDescription(1, 10).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1, 10),
+ },
+ },
+ "echo_startup_validate_force": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Ignore remote 'Required Min Echo RX Interval' setting").String,
+ Optional: true,
+ },
+ "echo_ipv4_source": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("BFD echo source IP address").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(regexp.MustCompile(`(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(%[\p{N}\p{L}]+)?`), ""),
+ stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""),
+ },
+ },
+ "echo_ipv4_bundle_per_member_minimum_interval_preferred_minimum_interval": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("The preferred minimum interval (in ms) for the BFD session").AddIntegerRangeDescription(15, 2000).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(15, 2000),
+ },
+ },
+ "trap_singlehop_pre_mapped": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Configure BFD trap pre-mapped").String,
+ Optional: true,
+ },
+ "multipath_locations": schema.ListNestedAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Specify a location").String,
+ Optional: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "location_name": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Specify a location").String,
+ Required: true,
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(regexp.MustCompile(`([a-zA-Z0-9_]*\d+/){1,2}([a-zA-Z0-9_]*\d+)`), ""),
+ },
+ },
+ },
+ },
+ },
+ "multihop_ttl_drop_threshold": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("TTL Drop Threshold").AddIntegerRangeDescription(0, 254).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(0, 254),
+ },
+ },
+ "dampening_initial_wait": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Initial delay before bringing up session").AddIntegerRangeDescription(1, 3600000).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1, 3600000),
+ },
+ },
+ "dampening_secondary_wait": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Secondary delay before bringing up session").AddIntegerRangeDescription(1, 3600000).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1, 3600000),
+ },
+ },
+ "dampening_maximum_wait": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Maximum delay before bringing up session").AddIntegerRangeDescription(1, 3600000).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1, 3600000),
+ },
+ },
+ "dampening_threshold": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Stability threshold to enable dampening").AddIntegerRangeDescription(60000, 3600000).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(60000, 3600000),
+ },
+ },
+ "dampening_extensions_down_monitoring": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Enable DOWN state session monitoring extensions").String,
+ Optional: true,
+ },
+ "dampening_disable": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Disable BFD dampening").String,
+ Optional: true,
+ },
+ "dampening_bundle_member_l3_only_mode": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Apply immediate dampening and only when failure is L3 specific").String,
+ Optional: true,
+ },
+ "dampening_bundle_member_initial_wait": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Initial delay before bringing up session").AddIntegerRangeDescription(1, 518400000).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1, 518400000),
+ },
+ },
+ "dampening_bundle_member_secondary_wait": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Secondary delay before bringing up session").AddIntegerRangeDescription(1, 518400000).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1, 518400000),
+ },
+ },
+ "dampening_bundle_member_maximum_wait": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Maximum delay before bringing up session").AddIntegerRangeDescription(1, 518400000).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1, 518400000),
+ },
+ },
+ "bundle_coexistence_bob_blb_inherit": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Use inheritence mechanism").String,
+ Optional: true,
+ },
+ "bundle_coexistence_bob_blb_logical": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Use BFD logical Bundle natively").String,
+ Optional: true,
+ },
+ "interfaces": schema.ListNestedAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Configure BFD on an interface").String,
+ Optional: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "interface_name": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Configure BFD on an interface").String,
+ Required: true,
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(regexp.MustCompile(`[a-zA-Z0-9.:_/-]+`), ""),
+ },
+ },
+ "echo_disable": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Disable BFD echo mode for this interface").String,
+ Optional: true,
+ },
+ "echo_ipv4_source": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("BFD echo source IP address").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(regexp.MustCompile(`(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(%[\p{N}\p{L}]+)?`), ""),
+ stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""),
+ },
+ },
+ "ipv6_checksum_disable": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Disable BFD ipv6 checksum mode for this interface").String,
+ Optional: true,
+ },
+ "disable": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Disable BFD for this interface").String,
+ Optional: true,
+ },
+ "local_address": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Local address to be used by BFD for this interface").String,
+ Optional: true,
+ },
+ "tx_interval": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("BFD TX Interval for this interface in microseconds").AddIntegerRangeDescription(3000, 30000000).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(3000, 30000000),
+ },
+ },
+ "rx_interval": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("BFD RX Interval for this interface in microseconds").AddIntegerRangeDescription(3000, 30000000).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(3000, 30000000),
+ },
+ },
+ "multiplier": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("BFD multiplier for this interface").AddIntegerRangeDescription(2, 50).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(2, 50),
+ },
+ },
+ },
+ },
+ },
+ "ipv6_checksum_disable": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Disable BFD checksum").String,
+ Optional: true,
+ },
+ },
+ }
+}
+
+func (r *BFDResource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) {
+ if req.ProviderData == nil {
+ return
+ }
+
+ r.client = req.ProviderData.(*client.Client)
+}
+
+func (r *BFDResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan BFD
+
+ // Read plan
+ diags := req.Plan.Get(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ var ops []client.SetOperation
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Create", plan.getPath()))
+
+ // Create object
+ body := plan.toBody(ctx)
+ ops = append(ops, client.SetOperation{Path: plan.getPath(), Body: body, Operation: client.Update})
+
+ emptyLeafsDelete := plan.getEmptyLeafsDelete(ctx)
+ tflog.Debug(ctx, fmt.Sprintf("List of empty leafs to delete: %+v", emptyLeafsDelete))
+
+ for _, i := range emptyLeafsDelete {
+ ops = append(ops, client.SetOperation{Path: i, Body: "", Operation: client.Delete})
+ }
+
+ _, diags = r.client.Set(ctx, plan.Device.ValueString(), ops...)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ plan.Id = types.StringValue(plan.getPath())
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Create finished successfully", plan.getPath()))
+
+ diags = resp.State.Set(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+}
+
+func (r *BFDResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state BFD
+
+ // Read state
+ diags := req.State.Get(ctx, &state)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", state.Id.ValueString()))
+
+ getResp, diags := r.client.Get(ctx, state.Device.ValueString(), state.Id.ValueString())
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ state.updateFromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal())
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", state.Id.ValueString()))
+
+ diags = resp.State.Set(ctx, &state)
+ resp.Diagnostics.Append(diags...)
+}
+
+func (r *BFDResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan, state BFD
+
+ // Read plan
+ diags := req.Plan.Get(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Read state
+ diags = req.State.Get(ctx, &state)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ var ops []client.SetOperation
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Update", plan.Id.ValueString()))
+
+ // Update object
+ body := plan.toBody(ctx)
+ ops = append(ops, client.SetOperation{Path: plan.getPath(), Body: body, Operation: client.Update})
+
+ deletedListItems := plan.getDeletedListItems(ctx, state)
+ tflog.Debug(ctx, fmt.Sprintf("List items to delete: %+v", deletedListItems))
+
+ for _, i := range deletedListItems {
+ ops = append(ops, client.SetOperation{Path: i, Body: "", Operation: client.Delete})
+ }
+
+ emptyLeafsDelete := plan.getEmptyLeafsDelete(ctx)
+ tflog.Debug(ctx, fmt.Sprintf("List of empty leafs to delete: %+v", emptyLeafsDelete))
+
+ for _, i := range emptyLeafsDelete {
+ ops = append(ops, client.SetOperation{Path: i, Body: "", Operation: client.Delete})
+ }
+
+ _, diags = r.client.Set(ctx, plan.Device.ValueString(), ops...)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Update finished successfully", plan.Id.ValueString()))
+
+ diags = resp.State.Set(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+}
+
+func (r *BFDResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state BFD
+
+ // Read state
+ diags := req.State.Get(ctx, &state)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Delete", state.Id.ValueString()))
+ var ops []client.SetOperation
+ deleteMode := "all"
+ if state.DeleteMode.ValueString() == "all" {
+ deleteMode = "all"
+ } else if state.DeleteMode.ValueString() == "attributes" {
+ deleteMode = "attributes"
+ }
+
+ if deleteMode == "all" {
+ ops = append(ops, client.SetOperation{Path: state.Id.ValueString(), Body: "", Operation: client.Delete})
+ } else {
+ deletePaths := state.getDeletePaths(ctx)
+ tflog.Debug(ctx, fmt.Sprintf("Paths to delete: %+v", deletePaths))
+
+ for _, i := range deletePaths {
+ ops = append(ops, client.SetOperation{Path: i, Body: "", Operation: client.Delete})
+ }
+ }
+
+ _, diags = r.client.Set(ctx, state.Device.ValueString(), ops...)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Delete finished successfully", state.Id.ValueString()))
+
+ resp.State.RemoveResource(ctx)
+}
+
+func (r *BFDResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
diff --git a/internal/provider/resource_iosxr_bfd_test.go b/internal/provider/resource_iosxr_bfd_test.go
new file mode 100644
index 00000000..98f2ca19
--- /dev/null
+++ b/internal/provider/resource_iosxr_bfd_test.go
@@ -0,0 +1,129 @@
+// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+// Code generated by "gen/generator.go"; DO NOT EDIT.
+
+package provider
+
+import (
+ "os"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+func TestAccIosxrBFD(t *testing.T) {
+ var checks []resource.TestCheckFunc
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "echo_disable", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "echo_latency_detect_percentage", "200"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "echo_latency_detect_count", "10"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "echo_startup_validate_force", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "echo_ipv4_source", "10.1.1.1"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "echo_ipv4_bundle_per_member_minimum_interval_preferred_minimum_interval", "200"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "trap_singlehop_pre_mapped", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "multipath_locations.0.location_name", "0/0/CPU0"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "multihop_ttl_drop_threshold", "200"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "dampening_initial_wait", "3600"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "dampening_secondary_wait", "3200"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "dampening_maximum_wait", "3100"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "dampening_threshold", "60000"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "dampening_extensions_down_monitoring", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "dampening_disable", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "dampening_bundle_member_l3_only_mode", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "dampening_bundle_member_initial_wait", "5184"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "dampening_bundle_member_secondary_wait", "6184"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "dampening_bundle_member_maximum_wait", "7184"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "bundle_coexistence_bob_blb_inherit", "false"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "bundle_coexistence_bob_blb_logical", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "interfaces.0.interface_name", "GigabitEthernet0/0/0/0"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "interfaces.0.echo_disable", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "interfaces.0.echo_ipv4_source", "12.1.1.1"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "interfaces.0.ipv6_checksum_disable", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "interfaces.0.disable", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "interfaces.0.local_address", "33.33.31.1"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "interfaces.0.tx_interval", "3200"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "interfaces.0.rx_interval", "4200"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "interfaces.0.multiplier", "40"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_bfd.test", "ipv6_checksum_disable", "true"))
+ var steps []resource.TestStep
+ if os.Getenv("SKIP_MINIMUM_TEST") == "" {
+ steps = append(steps, resource.TestStep{
+ Config: testAccIosxrBFDConfig_minimum(),
+ })
+ }
+ steps = append(steps, resource.TestStep{
+ Config: testAccIosxrBFDConfig_all(),
+ Check: resource.ComposeTestCheckFunc(checks...),
+ })
+ steps = append(steps, resource.TestStep{
+ ResourceName: "iosxr_bfd.test",
+ ImportState: true,
+ ImportStateId: "Cisco-IOS-XR-um-bfd-sbfd-cfg:/bfd",
+ })
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: steps,
+ })
+}
+
+func testAccIosxrBFDConfig_minimum() string {
+ config := `resource "iosxr_bfd" "test" {` + "\n"
+ config += `}` + "\n"
+ return config
+}
+
+func testAccIosxrBFDConfig_all() string {
+ config := `resource "iosxr_bfd" "test" {` + "\n"
+ config += ` echo_disable = true` + "\n"
+ config += ` echo_latency_detect_percentage = 200` + "\n"
+ config += ` echo_latency_detect_count = 10` + "\n"
+ config += ` echo_startup_validate_force = true` + "\n"
+ config += ` echo_ipv4_source = "10.1.1.1"` + "\n"
+ config += ` echo_ipv4_bundle_per_member_minimum_interval_preferred_minimum_interval = 200` + "\n"
+ config += ` trap_singlehop_pre_mapped = true` + "\n"
+ config += ` multipath_locations = [{` + "\n"
+ config += ` location_name = "0/0/CPU0"` + "\n"
+ config += ` }]` + "\n"
+ config += ` multihop_ttl_drop_threshold = 200` + "\n"
+ config += ` dampening_initial_wait = 3600` + "\n"
+ config += ` dampening_secondary_wait = 3200` + "\n"
+ config += ` dampening_maximum_wait = 3100` + "\n"
+ config += ` dampening_threshold = 60000` + "\n"
+ config += ` dampening_extensions_down_monitoring = true` + "\n"
+ config += ` dampening_disable = true` + "\n"
+ config += ` dampening_bundle_member_l3_only_mode = true` + "\n"
+ config += ` dampening_bundle_member_initial_wait = 5184` + "\n"
+ config += ` dampening_bundle_member_secondary_wait = 6184` + "\n"
+ config += ` dampening_bundle_member_maximum_wait = 7184` + "\n"
+ config += ` bundle_coexistence_bob_blb_inherit = false` + "\n"
+ config += ` bundle_coexistence_bob_blb_logical = true` + "\n"
+ config += ` interfaces = [{` + "\n"
+ config += ` interface_name = "GigabitEthernet0/0/0/0"` + "\n"
+ config += ` echo_disable = true` + "\n"
+ config += ` echo_ipv4_source = "12.1.1.1"` + "\n"
+ config += ` ipv6_checksum_disable = true` + "\n"
+ config += ` disable = true` + "\n"
+ config += ` local_address = "33.33.31.1"` + "\n"
+ config += ` tx_interval = 3200` + "\n"
+ config += ` rx_interval = 4200` + "\n"
+ config += ` multiplier = 40` + "\n"
+ config += ` }]` + "\n"
+ config += ` ipv6_checksum_disable = true` + "\n"
+ config += `}` + "\n"
+ return config
+}
diff --git a/internal/provider/resource_iosxr_flow_exporter_map.go b/internal/provider/resource_iosxr_flow_exporter_map.go
new file mode 100644
index 00000000..8005adf5
--- /dev/null
+++ b/internal/provider/resource_iosxr_flow_exporter_map.go
@@ -0,0 +1,365 @@
+// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+// Code generated by "gen/generator.go"; DO NOT EDIT.
+
+package provider
+
+import (
+ "context"
+ "fmt"
+ "regexp"
+
+ "github.com/CiscoDevNet/terraform-provider-iosxr/internal/provider/client"
+ "github.com/CiscoDevNet/terraform-provider-iosxr/internal/provider/helpers"
+ "github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/resource"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
+)
+
+func NewFlowExporterMapResource() resource.Resource {
+ return &FlowExporterMapResource{}
+}
+
+type FlowExporterMapResource struct {
+ client *client.Client
+}
+
+func (r *FlowExporterMapResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_flow_exporter_map"
+}
+
+func (r *FlowExporterMapResource) 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: "This resource can manage the Flow Exporter Map configuration.",
+
+ Attributes: map[string]schema.Attribute{
+ "device": schema.StringAttribute{
+ MarkdownDescription: "A device name from the provider configuration.",
+ Optional: true,
+ },
+ "id": schema.StringAttribute{
+ MarkdownDescription: "The path of the object.",
+ Computed: true,
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.UseStateForUnknown(),
+ },
+ },
+ "exporter_maps": schema.ListNestedAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Exporter map name - maximum 32 characters").String,
+ Optional: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "exporter_map_name": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Exporter map name - maximum 32 characters").String,
+ Required: true,
+ Validators: []validator.String{
+ stringvalidator.LengthBetween(1, 32),
+ stringvalidator.RegexMatches(regexp.MustCompile(`[\w\-\.:,_@#%$\+=\|;]+`), ""),
+ },
+ },
+ "destination_ipv4_address": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Destination IPv4 address").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(regexp.MustCompile(`(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(%[\p{N}\p{L}]+)?`), ""),
+ stringvalidator.RegexMatches(regexp.MustCompile(`[0-9\.]*`), ""),
+ },
+ },
+ "destination_ipv6_address": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Destination IPv6 address").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(regexp.MustCompile(`((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(%[\p{N}\p{L}]+)?`), ""),
+ stringvalidator.RegexMatches(regexp.MustCompile(`(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(%.+)?`), ""),
+ stringvalidator.RegexMatches(regexp.MustCompile(`[0-9a-fA-F:\.]*`), ""),
+ },
+ },
+ "destination_vrf": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Configure VRF to be used for reaching export destination").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.LengthBetween(1, 32),
+ stringvalidator.RegexMatches(regexp.MustCompile(`[\w\-\.:,_@#%$\+=\|;]+`), ""),
+ },
+ },
+ "source": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Source interface").String,
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(regexp.MustCompile(`[a-zA-Z0-9.:_/-]+`), ""),
+ },
+ },
+ "dscp": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Specify DSCP value for ipv4 export packets or traffic-class for ipv6 export packets").AddIntegerRangeDescription(0, 63).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(0, 63),
+ },
+ },
+ "packet_length": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Export Packet maximum L3 length, should conform to outgoing interface mtu").AddIntegerRangeDescription(512, 9000).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(512, 9000),
+ },
+ },
+ "transport_udp": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Use UDP as transport protocol").AddIntegerRangeDescription(1024, 65535).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1024, 65535),
+ },
+ },
+ "dfbit_set": schema.BoolAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Set Export Packet Do Not Fragment Flag").String,
+ Optional: true,
+ },
+ "version_export_format": schema.StringAttribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Specify export format").AddStringEnumDescription("ipfix", "protobuf", "sflow", "v9").String,
+ Required: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf("ipfix", "protobuf", "sflow", "v9"),
+ },
+ },
+ "version_template_data_timeout": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Specify custom timeout for the template").AddIntegerRangeDescription(1, 604800).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1, 604800),
+ },
+ },
+ "version_template_options_timeout": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Specify custom timeout for the template").AddIntegerRangeDescription(1, 604800).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1, 604800),
+ },
+ },
+ "version_template_timeout": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Specify custom timeout for the template").AddIntegerRangeDescription(1, 604800).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1, 604800),
+ },
+ },
+ "version_options_interface_table_timeout": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Specify export timeout").AddIntegerRangeDescription(1, 604800).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1, 604800),
+ },
+ },
+ "version_options_sampler_table_timeout": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Specify export timeout").AddIntegerRangeDescription(1, 604800).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1, 604800),
+ },
+ },
+ "version_options_class_table_timeout": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Specify export timeout").AddIntegerRangeDescription(1, 604800).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1, 604800),
+ },
+ },
+ "version_options_vrf_table_timeout": schema.Int64Attribute{
+ MarkdownDescription: helpers.NewAttributeDescription("Specify export timeout").AddIntegerRangeDescription(1, 604800).String,
+ Optional: true,
+ Validators: []validator.Int64{
+ int64validator.Between(1, 604800),
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+}
+
+func (r *FlowExporterMapResource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) {
+ if req.ProviderData == nil {
+ return
+ }
+
+ r.client = req.ProviderData.(*client.Client)
+}
+
+func (r *FlowExporterMapResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var plan FlowExporterMap
+
+ // Read plan
+ diags := req.Plan.Get(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ var ops []client.SetOperation
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Create", plan.getPath()))
+
+ // Create object
+ body := plan.toBody(ctx)
+ ops = append(ops, client.SetOperation{Path: plan.getPath(), Body: body, Operation: client.Update})
+
+ emptyLeafsDelete := plan.getEmptyLeafsDelete(ctx)
+ tflog.Debug(ctx, fmt.Sprintf("List of empty leafs to delete: %+v", emptyLeafsDelete))
+
+ for _, i := range emptyLeafsDelete {
+ ops = append(ops, client.SetOperation{Path: i, Body: "", Operation: client.Delete})
+ }
+
+ _, diags = r.client.Set(ctx, plan.Device.ValueString(), ops...)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ plan.Id = types.StringValue(plan.getPath())
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Create finished successfully", plan.getPath()))
+
+ diags = resp.State.Set(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+}
+
+func (r *FlowExporterMapResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var state FlowExporterMap
+
+ // Read state
+ diags := req.State.Get(ctx, &state)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", state.Id.ValueString()))
+
+ getResp, diags := r.client.Get(ctx, state.Device.ValueString(), state.Id.ValueString())
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ state.updateFromBody(ctx, getResp.Notification[0].Update[0].Val.GetJsonIetfVal())
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", state.Id.ValueString()))
+
+ diags = resp.State.Set(ctx, &state)
+ resp.Diagnostics.Append(diags...)
+}
+
+func (r *FlowExporterMapResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var plan, state FlowExporterMap
+
+ // Read plan
+ diags := req.Plan.Get(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Read state
+ diags = req.State.Get(ctx, &state)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ var ops []client.SetOperation
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Update", plan.Id.ValueString()))
+
+ // Update object
+ body := plan.toBody(ctx)
+ ops = append(ops, client.SetOperation{Path: plan.getPath(), Body: body, Operation: client.Update})
+
+ deletedListItems := plan.getDeletedListItems(ctx, state)
+ tflog.Debug(ctx, fmt.Sprintf("List items to delete: %+v", deletedListItems))
+
+ for _, i := range deletedListItems {
+ ops = append(ops, client.SetOperation{Path: i, Body: "", Operation: client.Delete})
+ }
+
+ emptyLeafsDelete := plan.getEmptyLeafsDelete(ctx)
+ tflog.Debug(ctx, fmt.Sprintf("List of empty leafs to delete: %+v", emptyLeafsDelete))
+
+ for _, i := range emptyLeafsDelete {
+ ops = append(ops, client.SetOperation{Path: i, Body: "", Operation: client.Delete})
+ }
+
+ _, diags = r.client.Set(ctx, plan.Device.ValueString(), ops...)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Update finished successfully", plan.Id.ValueString()))
+
+ diags = resp.State.Set(ctx, &plan)
+ resp.Diagnostics.Append(diags...)
+}
+
+func (r *FlowExporterMapResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var state FlowExporterMap
+
+ // Read state
+ diags := req.State.Get(ctx, &state)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Delete", state.Id.ValueString()))
+ var ops []client.SetOperation
+ deleteMode := "all"
+
+ if deleteMode == "all" {
+ ops = append(ops, client.SetOperation{Path: state.Id.ValueString(), Body: "", Operation: client.Delete})
+ } else {
+ deletePaths := state.getDeletePaths(ctx)
+ tflog.Debug(ctx, fmt.Sprintf("Paths to delete: %+v", deletePaths))
+
+ for _, i := range deletePaths {
+ ops = append(ops, client.SetOperation{Path: i, Body: "", Operation: client.Delete})
+ }
+ }
+
+ _, diags = r.client.Set(ctx, state.Device.ValueString(), ops...)
+ resp.Diagnostics.Append(diags...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("%s: Delete finished successfully", state.Id.ValueString()))
+
+ resp.State.RemoveResource(ctx)
+}
+
+func (r *FlowExporterMapResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
+}
diff --git a/internal/provider/resource_iosxr_flow_exporter_map_test.go b/internal/provider/resource_iosxr_flow_exporter_map_test.go
new file mode 100644
index 00000000..c57c85ed
--- /dev/null
+++ b/internal/provider/resource_iosxr_flow_exporter_map_test.go
@@ -0,0 +1,99 @@
+// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
+// All rights reserved.
+//
+// Licensed under the Mozilla Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://mozilla.org/MPL/2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: MPL-2.0
+
+// Code generated by "gen/generator.go"; DO NOT EDIT.
+
+package provider
+
+import (
+ "os"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+func TestAccIosxrFlowExporterMap(t *testing.T) {
+ var checks []resource.TestCheckFunc
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.exporter_map_name", "TEST"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.destination_ipv4_address", "10.1.1.1"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.destination_ipv6_address", "1::1"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.destination_vrf", "28"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.source", "10.1.1.4"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.dscp", "62"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.packet_length", "512"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.transport_udp", "1033"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.dfbit_set", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.version_export_format", "true"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.version_template_data_timeout", "1024"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.version_template_options_timeout", "3033"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.version_template_timeout", "2222"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.version_options_interface_table_timeout", "6048"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.version_options_sampler_table_timeout", "4096"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.version_options_class_table_timeout", "255"))
+ checks = append(checks, resource.TestCheckResourceAttr("iosxr_flow_exporter_map.test", "exporter_maps.0.version_options_vrf_table_timeout", "122"))
+ var steps []resource.TestStep
+ if os.Getenv("SKIP_MINIMUM_TEST") == "" {
+ steps = append(steps, resource.TestStep{
+ Config: testAccIosxrFlowExporterMapConfig_minimum(),
+ })
+ }
+ steps = append(steps, resource.TestStep{
+ Config: testAccIosxrFlowExporterMapConfig_all(),
+ Check: resource.ComposeTestCheckFunc(checks...),
+ })
+ steps = append(steps, resource.TestStep{
+ ResourceName: "iosxr_flow_exporter_map.test",
+ ImportState: true,
+ ImportStateId: "Cisco-IOS-XR-um-flow-cfg:/flow/exporter-maps",
+ })
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+ Steps: steps,
+ })
+}
+
+func testAccIosxrFlowExporterMapConfig_minimum() string {
+ config := `resource "iosxr_flow_exporter_map" "test" {` + "\n"
+ config += `}` + "\n"
+ return config
+}
+
+func testAccIosxrFlowExporterMapConfig_all() string {
+ config := `resource "iosxr_flow_exporter_map" "test" {` + "\n"
+ config += ` exporter_maps = [{` + "\n"
+ config += ` exporter_map_name = "TEST"` + "\n"
+ config += ` destination_ipv4_address = "10.1.1.1"` + "\n"
+ config += ` destination_ipv6_address = "1::1"` + "\n"
+ config += ` destination_vrf = "28"` + "\n"
+ config += ` source = "10.1.1.4"` + "\n"
+ config += ` dscp = 62` + "\n"
+ config += ` packet_length = 512` + "\n"
+ config += ` transport_udp = 1033` + "\n"
+ config += ` dfbit_set = true` + "\n"
+ config += ` version_export_format = "true"` + "\n"
+ config += ` version_template_data_timeout = 1024` + "\n"
+ config += ` version_template_options_timeout = 3033` + "\n"
+ config += ` version_template_timeout = 2222` + "\n"
+ config += ` version_options_interface_table_timeout = 6048` + "\n"
+ config += ` version_options_sampler_table_timeout = 4096` + "\n"
+ config += ` version_options_class_table_timeout = 255` + "\n"
+ config += ` version_options_vrf_table_timeout = 122` + "\n"
+ config += ` }]` + "\n"
+ config += `}` + "\n"
+ return config
+}
diff --git a/templates/guides/changelog.md.tmpl b/templates/guides/changelog.md.tmpl
index ee1469d4..34f4a7f8 100644
--- a/templates/guides/changelog.md.tmpl
+++ b/templates/guides/changelog.md.tmpl
@@ -33,6 +33,10 @@ description: |-
- Add `iosxr_rd_set` resource and data source
- Add `contact` and `location` attributes to `iosxr_snmp_server` resource and data source
- Add `police_conform_action_transmit`, `police_conform_action_drop`, `police_exceed_action_transmit`, `police_exceed_action_drop`, `police_violate_action_transmit`, `police_violate_action_drop` attributes to `iosxr_policy_map_qos` resource and data source
+- Add `iosxr_bfd` resource and data source
+- Add `iosxr_flow_exporter_map` resource and data source
+
+
## 0.2.1