From 430bf136ab490a2db8b651798e29cd4e1d0117c6 Mon Sep 17 00:00:00 2001 From: narasing01 <134702921+narasing01@users.noreply.github.com> Date: Sun, 10 Sep 2023 21:49:17 +0530 Subject: [PATCH] Add router hsrp ipv6 resources and data sources (#178) --- ...r_hsrp_interface_address_family_ipv6_v1.md | 76 +++ ...r_hsrp_interface_address_family_ipv6_v2.md | 76 +++ ...r_hsrp_interface_address_family_ipv6_v1.md | 118 ++++ ...r_hsrp_interface_address_family_ipv6_v2.md | 123 ++++ .../data-source.tf | 4 + .../data-source.tf | 4 + .../import.sh | 1 + .../resource.tf | 27 + .../import.sh | 1 + .../resource.tf | 32 + gen/definitions/logging_vrf.yaml | 21 + ...nterface_address_family_ipv6_group_v1.yaml | 61 ++ ...nterface_address_family_ipv6_group_v2.yaml | 60 ++ ...r_hsrp_interface_address_family_ipv6_v1.go | 202 ++++++ ...p_interface_address_family_ipv6_v1_test.go | 91 +++ ...r_hsrp_interface_address_family_ipv6_v2.go | 202 ++++++ ...p_interface_address_family_ipv6_v2_test.go | 95 +++ ...r_hsrp_interface_address_family_ipv6_v1.go | 613 ++++++++++++++++++ ...r_hsrp_interface_address_family_ipv6_v2.go | 613 ++++++++++++++++++ ...r_hsrp_interface_address_family_ipv6_v1.go | 417 ++++++++++++ ...p_interface_address_family_ipv6_v1_test.go | 102 +++ ...r_hsrp_interface_address_family_ipv6_v2.go | 417 ++++++++++++ ...p_interface_address_family_ipv6_v2_test.go | 106 +++ 23 files changed, 3462 insertions(+) create mode 100644 docs/data-sources/router_hsrp_interface_address_family_ipv6_v1.md create mode 100644 docs/data-sources/router_hsrp_interface_address_family_ipv6_v2.md create mode 100644 docs/resources/router_hsrp_interface_address_family_ipv6_v1.md create mode 100644 docs/resources/router_hsrp_interface_address_family_ipv6_v2.md create mode 100644 examples/data-sources/iosxr_router_hsrp_interface_address_family_ipv6_v1/data-source.tf create mode 100644 examples/data-sources/iosxr_router_hsrp_interface_address_family_ipv6_v2/data-source.tf create mode 100644 examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v1/import.sh create mode 100644 examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v1/resource.tf create mode 100644 examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v2/import.sh create mode 100644 examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v2/resource.tf create mode 100644 gen/definitions/router_hsrp_interface_address_family_ipv6_group_v1.yaml create mode 100644 gen/definitions/router_hsrp_interface_address_family_ipv6_group_v2.yaml create mode 100644 internal/provider/data_source_iosxr_router_hsrp_interface_address_family_ipv6_v1.go create mode 100644 internal/provider/data_source_iosxr_router_hsrp_interface_address_family_ipv6_v1_test.go create mode 100644 internal/provider/data_source_iosxr_router_hsrp_interface_address_family_ipv6_v2.go create mode 100644 internal/provider/data_source_iosxr_router_hsrp_interface_address_family_ipv6_v2_test.go create mode 100644 internal/provider/model_iosxr_router_hsrp_interface_address_family_ipv6_v1.go create mode 100644 internal/provider/model_iosxr_router_hsrp_interface_address_family_ipv6_v2.go create mode 100644 internal/provider/resource_iosxr_router_hsrp_interface_address_family_ipv6_v1.go create mode 100644 internal/provider/resource_iosxr_router_hsrp_interface_address_family_ipv6_v1_test.go create mode 100644 internal/provider/resource_iosxr_router_hsrp_interface_address_family_ipv6_v2.go create mode 100644 internal/provider/resource_iosxr_router_hsrp_interface_address_family_ipv6_v2_test.go diff --git a/docs/data-sources/router_hsrp_interface_address_family_ipv6_v1.md b/docs/data-sources/router_hsrp_interface_address_family_ipv6_v1.md new file mode 100644 index 00000000..d35b189f --- /dev/null +++ b/docs/data-sources/router_hsrp_interface_address_family_ipv6_v1.md @@ -0,0 +1,76 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "iosxr_router_hsrp_interface_address_family_ipv6_v1 Data Source - terraform-provider-iosxr" +subcategory: "HSRP" +description: |- + This data source can read the Router HSRP Interface Address Family IPv6 V1 configuration. +--- + +# iosxr_router_hsrp_interface_address_family_ipv6_v1 (Data Source) + +This data source can read the Router HSRP Interface Address Family IPv6 V1 configuration. + +## Example Usage + +```terraform +data "iosxr_router_hsrp_interface_address_family_ipv6_v1" "example" { + interface_name = "GigabitEthernet0/0/0/1" + group_number_version_1_id = 135 +} +``` + + +## Schema + +### Required + +- `group_number_version_1_id` (Number) group number version 1 +- `interface_name` (String) HSRP interface configuration subcommands + +### Optional + +- `device` (String) A device name from the provider configuration. + +### Read-Only + +- `address_globals` (Attributes List) Global HSRP IPv6 address (see [below for nested schema](#nestedatt--address_globals)) +- `address_link_local_autoconfig_legacy_compatible` (Boolean) Autoconfigure for Legacy compatibility (with IOS/NX-OS) +- `address_link_local_ipv6_address` (String) HSRP IPv6 linklocal address +- `bfd_fast_detect_peer_interface` (String) Select an interface over which to run BFD +- `bfd_fast_detect_peer_ipv6` (String) BFD peer interface IPv6 address +- `id` (String) The path of the retrieved object. +- `mac_address` (String) Use specified mac address for the virtual router +- `name` (String) MGO session name +- `preempt_delay` (Number) Wait before preempting +- `priority` (Number) Priority level +- `timers_hold_time` (Number) Hold time in seconds +- `timers_hold_time2` (Number) Hold time in seconds +- `timers_msec` (Number) Specify hellotime in milliseconds +- `timers_msec2` (Number) Specify hold time in milliseconds +- `track_interfaces` (Attributes List) Configure tracking (see [below for nested schema](#nestedatt--track_interfaces)) +- `track_objects` (Attributes List) Object tracking (see [below for nested schema](#nestedatt--track_objects)) + + +### Nested Schema for `address_globals` + +Read-Only: + +- `address` (String) Set Global HSRP IPv6 address + + + +### Nested Schema for `track_interfaces` + +Read-Only: + +- `priority_decrement` (Number) Priority decrement +- `track_name` (String) Configure tracking + + + +### Nested Schema for `track_objects` + +Read-Only: + +- `object_name` (String) Object tracking +- `priority_decrement` (Number) Priority decrement diff --git a/docs/data-sources/router_hsrp_interface_address_family_ipv6_v2.md b/docs/data-sources/router_hsrp_interface_address_family_ipv6_v2.md new file mode 100644 index 00000000..84b3a9ae --- /dev/null +++ b/docs/data-sources/router_hsrp_interface_address_family_ipv6_v2.md @@ -0,0 +1,76 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "iosxr_router_hsrp_interface_address_family_ipv6_v2 Data Source - terraform-provider-iosxr" +subcategory: "HSRP" +description: |- + This data source can read the Router HSRP Interface Address Family IPv6 V2 configuration. +--- + +# iosxr_router_hsrp_interface_address_family_ipv6_v2 (Data Source) + +This data source can read the Router HSRP Interface Address Family IPv6 V2 configuration. + +## Example Usage + +```terraform +data "iosxr_router_hsrp_interface_address_family_ipv6_v2" "example" { + interface_name = "GigabitEthernet0/0/0/2" + group_number_version_2_id = 4055 +} +``` + + +## Schema + +### Required + +- `group_number_version_2_id` (Number) group number version 2 +- `interface_name` (String) HSRP interface configuration subcommands + +### Optional + +- `device` (String) A device name from the provider configuration. + +### Read-Only + +- `address_globals` (Attributes List) Global HSRP IPv6 address (see [below for nested schema](#nestedatt--address_globals)) +- `address_link_local_autoconfig_legacy_compatible` (Boolean) Autoconfigure for Legacy compatibility (with IOS/NX-OS) +- `address_link_local_ipv6_address` (String) HSRP IPv6 linklocal address +- `bfd_fast_detect_peer_interface` (String) Select an interface over which to run BFD +- `bfd_fast_detect_peer_ipv6` (String) BFD peer interface IPv6 address +- `id` (String) The path of the retrieved object. +- `mac_address` (String) Use specified mac address for the virtual router +- `name` (String) MGO session name +- `preempt_delay` (Number) Wait before preempting +- `priority` (Number) Priority level +- `timers_hold_time` (Number) Hold time in seconds +- `timers_hold_time2` (Number) Hold time in seconds +- `timers_msec` (Number) Specify hellotime in milliseconds +- `timers_msec2` (Number) Specify hold time in milliseconds +- `track_interfaces` (Attributes List) Configure tracking (see [below for nested schema](#nestedatt--track_interfaces)) +- `track_objects` (Attributes List) Object tracking (see [below for nested schema](#nestedatt--track_objects)) + + +### Nested Schema for `address_globals` + +Read-Only: + +- `address` (String) Set Global HSRP IPv6 address + + + +### Nested Schema for `track_interfaces` + +Read-Only: + +- `priority_decrement` (Number) Priority decrement +- `track_name` (String) Configure tracking + + + +### Nested Schema for `track_objects` + +Read-Only: + +- `object_name` (String) Object tracking +- `priority_decrement` (Number) Priority decrement diff --git a/docs/resources/router_hsrp_interface_address_family_ipv6_v1.md b/docs/resources/router_hsrp_interface_address_family_ipv6_v1.md new file mode 100644 index 00000000..d56ba87f --- /dev/null +++ b/docs/resources/router_hsrp_interface_address_family_ipv6_v1.md @@ -0,0 +1,118 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "iosxr_router_hsrp_interface_address_family_ipv6_v1 Resource - terraform-provider-iosxr" +subcategory: "HSRP" +description: |- + This resource can manage the Router HSRP Interface Address Family IPv6 V1 configuration. +--- + +# iosxr_router_hsrp_interface_address_family_ipv6_v1 (Resource) + +This resource can manage the Router HSRP Interface Address Family IPv6 V1 configuration. + +## Example Usage + +```terraform +resource "iosxr_router_hsrp_interface_address_family_ipv6_v1" "example" { + interface_name = "GigabitEthernet0/0/0/1" + group_number_version_1_id = 135 + name = "gp1" + mac_address = "00:02:00:01:00:01" + timers_hold_time = 10 + timers_hold_time2 = 20 + timers_msec = 100 + timers_msec2 = 130 + preempt_delay = 256 + priority = 244 + bfd_fast_detect_peer_ipv6 = "fe80::240:d0ff:fe48:4672" + bfd_fast_detect_peer_interface = "GigabitEthernet0/0/0/2" + track_objects = [ + { + object_name = "TOBJ1" + priority_decrement = 10 + } + ] + track_interfaces = [ + { + track_name = "GigabitEthernet0/0/0/4" + priority_decrement = 244 + } + ] + address_link_local_autoconfig_legacy_compatible = true +} +``` + + +## Schema + +### Required + +- `group_number_version_1_id` (Number) group number version 1 + - Range: `0`-`255` +- `interface_name` (String) HSRP interface configuration subcommands + +### Optional + +- `address_globals` (Attributes List) Global HSRP IPv6 address (see [below for nested schema](#nestedatt--address_globals)) +- `address_link_local_autoconfig_legacy_compatible` (Boolean) Autoconfigure for Legacy compatibility (with IOS/NX-OS) +- `address_link_local_ipv6_address` (String) HSRP IPv6 linklocal address +- `bfd_fast_detect_peer_interface` (String) Select an interface over which to run BFD +- `bfd_fast_detect_peer_ipv6` (String) BFD peer interface IPv6 address +- `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. +- `mac_address` (String) Use specified mac address for the virtual router +- `name` (String) MGO session name +- `preempt_delay` (Number) Wait before preempting + - Range: `0`-`3600` +- `priority` (Number) Priority level + - Range: `0`-`255` +- `timers_hold_time` (Number) Hold time in seconds + - Range: `1`-`255` +- `timers_hold_time2` (Number) Hold time in seconds + - Range: `1`-`255` +- `timers_msec` (Number) Specify hellotime in milliseconds + - Range: `100`-`3000` +- `timers_msec2` (Number) Specify hold time in milliseconds + - Range: `100`-`3000` +- `track_interfaces` (Attributes List) Configure tracking (see [below for nested schema](#nestedatt--track_interfaces)) +- `track_objects` (Attributes List) Object tracking (see [below for nested schema](#nestedatt--track_objects)) + +### Read-Only + +- `id` (String) The path of the object. + + +### Nested Schema for `address_globals` + +Required: + +- `address` (String) Set Global HSRP IPv6 address + + + +### Nested Schema for `track_interfaces` + +Required: + +- `priority_decrement` (Number) Priority decrement + - Range: `1`-`255` +- `track_name` (String) Configure tracking + + + +### Nested Schema for `track_objects` + +Required: + +- `object_name` (String) Object tracking +- `priority_decrement` (Number) Priority decrement + - Range: `1`-`255` + +## Import + +Import is supported using the following syntax: + +```shell +terraform import iosxr_router_hsrp_interface_address_family_ipv6_v1.example "Cisco-IOS-XR-um-router-hsrp-cfg:/router/hsrp/interfaces/interface[interface-name=GigabitEthernet0/0/0/1]/address-family/ipv6/hsrp/group-number-version-1s/group-number-version-1[group-number-version-1-id=135]" +``` diff --git a/docs/resources/router_hsrp_interface_address_family_ipv6_v2.md b/docs/resources/router_hsrp_interface_address_family_ipv6_v2.md new file mode 100644 index 00000000..046bd4ec --- /dev/null +++ b/docs/resources/router_hsrp_interface_address_family_ipv6_v2.md @@ -0,0 +1,123 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "iosxr_router_hsrp_interface_address_family_ipv6_v2 Resource - terraform-provider-iosxr" +subcategory: "HSRP" +description: |- + This resource can manage the Router HSRP Interface Address Family IPv6 V2 configuration. +--- + +# iosxr_router_hsrp_interface_address_family_ipv6_v2 (Resource) + +This resource can manage the Router HSRP Interface Address Family IPv6 V2 configuration. + +## Example Usage + +```terraform +resource "iosxr_router_hsrp_interface_address_family_ipv6_v2" "example" { + interface_name = "GigabitEthernet0/0/0/2" + group_number_version_2_id = 4055 + name = "gp2" + mac_address = "00:01:00:02:00:02" + timers_hold_time = 10 + timers_hold_time2 = 20 + timers_msec = 100 + timers_msec2 = 130 + preempt_delay = 256 + priority = 244 + bfd_fast_detect_peer_ipv6 = "fe80::240:d0ff:fe48:4672" + bfd_fast_detect_peer_interface = "GigabitEthernet0/0/0/3" + track_objects = [ + { + object_name = "TOBJ2" + priority_decrement = 10 + } + ] + track_interfaces = [ + { + track_name = "GigabitEthernet0/0/0/4" + priority_decrement = 244 + } + ] + address_globals = [ + { + address = "2001:db8:cafe:2100::bad1:1010" + } + ] + address_link_local_autoconfig_legacy_compatible = true +} +``` + + +## Schema + +### Required + +- `group_number_version_2_id` (Number) group number version 2 + - Range: `0`-`4095` +- `interface_name` (String) HSRP interface configuration subcommands + +### Optional + +- `address_globals` (Attributes List) Global HSRP IPv6 address (see [below for nested schema](#nestedatt--address_globals)) +- `address_link_local_autoconfig_legacy_compatible` (Boolean) Autoconfigure for Legacy compatibility (with IOS/NX-OS) +- `address_link_local_ipv6_address` (String) HSRP IPv6 linklocal address +- `bfd_fast_detect_peer_interface` (String) Select an interface over which to run BFD +- `bfd_fast_detect_peer_ipv6` (String) BFD peer interface IPv6 address +- `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. +- `mac_address` (String) Use specified mac address for the virtual router +- `name` (String) MGO session name +- `preempt_delay` (Number) Wait before preempting + - Range: `0`-`3600` +- `priority` (Number) Priority level + - Range: `0`-`255` +- `timers_hold_time` (Number) Hold time in seconds + - Range: `1`-`255` +- `timers_hold_time2` (Number) Hold time in seconds + - Range: `1`-`255` +- `timers_msec` (Number) Specify hellotime in milliseconds + - Range: `100`-`3000` +- `timers_msec2` (Number) Specify hold time in milliseconds + - Range: `100`-`3000` +- `track_interfaces` (Attributes List) Configure tracking (see [below for nested schema](#nestedatt--track_interfaces)) +- `track_objects` (Attributes List) Object tracking (see [below for nested schema](#nestedatt--track_objects)) + +### Read-Only + +- `id` (String) The path of the object. + + +### Nested Schema for `address_globals` + +Required: + +- `address` (String) Set Global HSRP IPv6 address + + + +### Nested Schema for `track_interfaces` + +Required: + +- `priority_decrement` (Number) Priority decrement + - Range: `1`-`255` +- `track_name` (String) Configure tracking + + + +### Nested Schema for `track_objects` + +Required: + +- `object_name` (String) Object tracking +- `priority_decrement` (Number) Priority decrement + - Range: `1`-`255` + +## Import + +Import is supported using the following syntax: + +```shell +terraform import iosxr_router_hsrp_interface_address_family_ipv6_v2.example "Cisco-IOS-XR-um-router-hsrp-cfg:/router/hsrp/interfaces/interface[interface-name=GigabitEthernet0/0/0/2]/address-family/ipv6/hsrp/group-number-version-2s/group-number-version-2[group-number-version-2-id=4055]" +``` diff --git a/examples/data-sources/iosxr_router_hsrp_interface_address_family_ipv6_v1/data-source.tf b/examples/data-sources/iosxr_router_hsrp_interface_address_family_ipv6_v1/data-source.tf new file mode 100644 index 00000000..b3b0c47c --- /dev/null +++ b/examples/data-sources/iosxr_router_hsrp_interface_address_family_ipv6_v1/data-source.tf @@ -0,0 +1,4 @@ +data "iosxr_router_hsrp_interface_address_family_ipv6_v1" "example" { + interface_name = "GigabitEthernet0/0/0/1" + group_number_version_1_id = 135 +} diff --git a/examples/data-sources/iosxr_router_hsrp_interface_address_family_ipv6_v2/data-source.tf b/examples/data-sources/iosxr_router_hsrp_interface_address_family_ipv6_v2/data-source.tf new file mode 100644 index 00000000..090d28c0 --- /dev/null +++ b/examples/data-sources/iosxr_router_hsrp_interface_address_family_ipv6_v2/data-source.tf @@ -0,0 +1,4 @@ +data "iosxr_router_hsrp_interface_address_family_ipv6_v2" "example" { + interface_name = "GigabitEthernet0/0/0/2" + group_number_version_2_id = 4055 +} diff --git a/examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v1/import.sh b/examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v1/import.sh new file mode 100644 index 00000000..005cfb48 --- /dev/null +++ b/examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v1/import.sh @@ -0,0 +1 @@ +terraform import iosxr_router_hsrp_interface_address_family_ipv6_v1.example "Cisco-IOS-XR-um-router-hsrp-cfg:/router/hsrp/interfaces/interface[interface-name=GigabitEthernet0/0/0/1]/address-family/ipv6/hsrp/group-number-version-1s/group-number-version-1[group-number-version-1-id=135]" diff --git a/examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v1/resource.tf b/examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v1/resource.tf new file mode 100644 index 00000000..598ab997 --- /dev/null +++ b/examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v1/resource.tf @@ -0,0 +1,27 @@ +resource "iosxr_router_hsrp_interface_address_family_ipv6_v1" "example" { + interface_name = "GigabitEthernet0/0/0/1" + group_number_version_1_id = 135 + name = "gp1" + mac_address = "00:02:00:01:00:01" + timers_hold_time = 10 + timers_hold_time2 = 20 + timers_msec = 100 + timers_msec2 = 130 + preempt_delay = 256 + priority = 244 + bfd_fast_detect_peer_ipv6 = "fe80::240:d0ff:fe48:4672" + bfd_fast_detect_peer_interface = "GigabitEthernet0/0/0/2" + track_objects = [ + { + object_name = "TOBJ1" + priority_decrement = 10 + } + ] + track_interfaces = [ + { + track_name = "GigabitEthernet0/0/0/4" + priority_decrement = 244 + } + ] + address_link_local_autoconfig_legacy_compatible = true +} diff --git a/examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v2/import.sh b/examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v2/import.sh new file mode 100644 index 00000000..78104730 --- /dev/null +++ b/examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v2/import.sh @@ -0,0 +1 @@ +terraform import iosxr_router_hsrp_interface_address_family_ipv6_v2.example "Cisco-IOS-XR-um-router-hsrp-cfg:/router/hsrp/interfaces/interface[interface-name=GigabitEthernet0/0/0/2]/address-family/ipv6/hsrp/group-number-version-2s/group-number-version-2[group-number-version-2-id=4055]" diff --git a/examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v2/resource.tf b/examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v2/resource.tf new file mode 100644 index 00000000..d8b2260c --- /dev/null +++ b/examples/resources/iosxr_router_hsrp_interface_address_family_ipv6_v2/resource.tf @@ -0,0 +1,32 @@ +resource "iosxr_router_hsrp_interface_address_family_ipv6_v2" "example" { + interface_name = "GigabitEthernet0/0/0/2" + group_number_version_2_id = 4055 + name = "gp2" + mac_address = "00:01:00:02:00:02" + timers_hold_time = 10 + timers_hold_time2 = 20 + timers_msec = 100 + timers_msec2 = 130 + preempt_delay = 256 + priority = 244 + bfd_fast_detect_peer_ipv6 = "fe80::240:d0ff:fe48:4672" + bfd_fast_detect_peer_interface = "GigabitEthernet0/0/0/3" + track_objects = [ + { + object_name = "TOBJ2" + priority_decrement = 10 + } + ] + track_interfaces = [ + { + track_name = "GigabitEthernet0/0/0/4" + priority_decrement = 244 + } + ] + address_globals = [ + { + address = "2001:db8:cafe:2100::bad1:1010" + } + ] + address_link_local_autoconfig_legacy_compatible = true +} diff --git a/gen/definitions/logging_vrf.yaml b/gen/definitions/logging_vrf.yaml index 6355606a..7017cf44 100644 --- a/gen/definitions/logging_vrf.yaml +++ b/gen/definitions/logging_vrf.yaml @@ -14,6 +14,10 @@ attributes: example: 1.1.1.1 - yang_name: severity example: info + - yang_name: port + example: 514 + - yang_name: operator + example: equals - yang_name: host-ipv6-addresses/host-ipv6-address tf_name: host_ipv6_addresses type: List @@ -23,3 +27,20 @@ attributes: example: 2001::1 - yang_name: severity example: info + # - yang_name: host-names/host-name + # tf_name: host_names + # type: List + # exclude_test: true + # attributes: + # - yang_name: name + # example: host_name + # exclude_test: true + # - yang_name: severity + # example: 1 + # exclude_test: true + # - yang_name: port + # example: 3032 + # exclude_test: true + # - yang_name: operator + # example: true + # exclude_test: true diff --git a/gen/definitions/router_hsrp_interface_address_family_ipv6_group_v1.yaml b/gen/definitions/router_hsrp_interface_address_family_ipv6_group_v1.yaml new file mode 100644 index 00000000..95286fb2 --- /dev/null +++ b/gen/definitions/router_hsrp_interface_address_family_ipv6_group_v1.yaml @@ -0,0 +1,61 @@ +--- +name: Router HSRP Interface Address Family IPv6 V1 +path: Cisco-IOS-XR-um-router-hsrp-cfg:/router/hsrp/interfaces/interface[interface-name=%s]/address-family/ipv6/hsrp/group-number-version-1s/group-number-version-1[group-number-version-1-id=%v] +doc_category: HSRP +attributes: + - yang_name: interface-name + example: GigabitEthernet0/0/0/1 + - yang_name: group-number-version-1-id + example: 135 + - yang_name: name + example: gp1 + - yang_name: mac-address + example: 00:02:00:01:00:01 + - yang_name: timers/hold-time + example: 10 + - yang_name: timers/hold-time2 + example: 20 + - yang_name: timers/msec + example: 100 + - yang_name: timers/msec2 + example: 130 + - yang_name: preempt/delay + example: 256 + - yang_name: priority + example: 244 + - yang_name: bfd/fast-detect/peer/ipv6 + example: fe80::240:d0ff:fe48:4672 + - yang_name: bfd/fast-detect/peer/interface + example: GigabitEthernet0/0/0/2 + - yang_name: track-objects/track-object + tf_name: track_objects + type: List + attributes: + - yang_name: object-name + id: true + example: TOBJ1 + - yang_name: priority-decrement + example: 10 + - yang_name: track-interfaces/track-interface + tf_name: track_interfaces + type: List + attributes: + - yang_name: track-name + id: true + example: GigabitEthernet0/0/0/4 + - yang_name: priority-decrement + example: 244 + - yang_name: address/globals/global + tf_name: address_globals + exclude_test: true + type: List + attributes: + - yang_name: address + id: true + example: 2001:db8:cafe:2100::bad1:1010 + - yang_name: address/link-local/autoconfig/legacy-compatible + example: true + - yang_name: address/link-local/ipv6-address + example: fe80::240:d0ff:fe48:4672 + exclude_test: true + \ No newline at end of file diff --git a/gen/definitions/router_hsrp_interface_address_family_ipv6_group_v2.yaml b/gen/definitions/router_hsrp_interface_address_family_ipv6_group_v2.yaml new file mode 100644 index 00000000..845a1217 --- /dev/null +++ b/gen/definitions/router_hsrp_interface_address_family_ipv6_group_v2.yaml @@ -0,0 +1,60 @@ +--- +name: Router HSRP Interface Address Family IPv6 V2 +path: Cisco-IOS-XR-um-router-hsrp-cfg:/router/hsrp/interfaces/interface[interface-name=%s]/address-family/ipv6/hsrp/group-number-version-2s/group-number-version-2[group-number-version-2-id=%v] +doc_category: HSRP +attributes: + - yang_name: interface-name + example: GigabitEthernet0/0/0/2 + - yang_name: group-number-version-2-id + id: true + example: 4055 + - yang_name: name + example: gp2 + - yang_name: mac-address + example: 00:01:00:02:00:02 + - yang_name: timers/hold-time + example: 10 + - yang_name: timers/hold-time2 + example: 20 + - yang_name: timers/msec + example: 100 + - yang_name: timers/msec2 + example: 130 + - yang_name: preempt/delay + example: 256 + - yang_name: priority + example: 244 + - yang_name: bfd/fast-detect/peer/ipv6 + example: fe80::240:d0ff:fe48:4672 + - yang_name: bfd/fast-detect/peer/interface + example: GigabitEthernet0/0/0/3 + - yang_name: track-objects/track-object + tf_name: track_objects + type: List + attributes: + - yang_name: object-name + id: true + example: TOBJ2 + - yang_name: priority-decrement + example: 10 + - yang_name: track-interfaces/track-interface + tf_name: track_interfaces + type: List + attributes: + - yang_name: track-name + id: true + example: GigabitEthernet0/0/0/4 + - yang_name: priority-decrement + example: 244 + - yang_name: address/globals/global + tf_name: address_globals + type: List + attributes: + - yang_name: address + id: true + example: 2001:db8:cafe:2100::bad1:1010 + - yang_name: address/link-local/autoconfig/legacy-compatible + example: true + - yang_name: address/link-local/ipv6-address + example: fe80::240:d0ff:fe48:4672 + exclude_test: true \ No newline at end of file diff --git a/internal/provider/data_source_iosxr_router_hsrp_interface_address_family_ipv6_v1.go b/internal/provider/data_source_iosxr_router_hsrp_interface_address_family_ipv6_v1.go new file mode 100644 index 00000000..a1343ebb --- /dev/null +++ b/internal/provider/data_source_iosxr_router_hsrp_interface_address_family_ipv6_v1.go @@ -0,0 +1,202 @@ +// 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 = &RouterHSRPInterfaceAddressFamilyIPv6V1DataSource{} + _ datasource.DataSourceWithConfigure = &RouterHSRPInterfaceAddressFamilyIPv6V1DataSource{} +) + +func NewRouterHSRPInterfaceAddressFamilyIPv6V1DataSource() datasource.DataSource { + return &RouterHSRPInterfaceAddressFamilyIPv6V1DataSource{} +} + +type RouterHSRPInterfaceAddressFamilyIPv6V1DataSource struct { + client *client.Client +} + +func (d *RouterHSRPInterfaceAddressFamilyIPv6V1DataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_router_hsrp_interface_address_family_ipv6_v1" +} + +func (d *RouterHSRPInterfaceAddressFamilyIPv6V1DataSource) 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 Router HSRP Interface Address Family IPv6 V1 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, + }, + "interface_name": schema.StringAttribute{ + MarkdownDescription: "HSRP interface configuration subcommands", + Required: true, + }, + "group_number_version_1_id": schema.Int64Attribute{ + MarkdownDescription: "group number version 1", + Required: true, + }, + "name": schema.StringAttribute{ + MarkdownDescription: "MGO session name", + Computed: true, + }, + "mac_address": schema.StringAttribute{ + MarkdownDescription: "Use specified mac address for the virtual router", + Computed: true, + }, + "timers_hold_time": schema.Int64Attribute{ + MarkdownDescription: "Hold time in seconds", + Computed: true, + }, + "timers_hold_time2": schema.Int64Attribute{ + MarkdownDescription: "Hold time in seconds", + Computed: true, + }, + "timers_msec": schema.Int64Attribute{ + MarkdownDescription: "Specify hellotime in milliseconds", + Computed: true, + }, + "timers_msec2": schema.Int64Attribute{ + MarkdownDescription: "Specify hold time in milliseconds", + Computed: true, + }, + "preempt_delay": schema.Int64Attribute{ + MarkdownDescription: "Wait before preempting", + Computed: true, + }, + "priority": schema.Int64Attribute{ + MarkdownDescription: "Priority level", + Computed: true, + }, + "bfd_fast_detect_peer_ipv6": schema.StringAttribute{ + MarkdownDescription: "BFD peer interface IPv6 address", + Computed: true, + }, + "bfd_fast_detect_peer_interface": schema.StringAttribute{ + MarkdownDescription: "Select an interface over which to run BFD", + Computed: true, + }, + "track_objects": schema.ListNestedAttribute{ + MarkdownDescription: "Object tracking", + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "object_name": schema.StringAttribute{ + MarkdownDescription: "Object tracking", + Computed: true, + }, + "priority_decrement": schema.Int64Attribute{ + MarkdownDescription: "Priority decrement", + Computed: true, + }, + }, + }, + }, + "track_interfaces": schema.ListNestedAttribute{ + MarkdownDescription: "Configure tracking", + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "track_name": schema.StringAttribute{ + MarkdownDescription: "Configure tracking", + Computed: true, + }, + "priority_decrement": schema.Int64Attribute{ + MarkdownDescription: "Priority decrement", + Computed: true, + }, + }, + }, + }, + "address_globals": schema.ListNestedAttribute{ + MarkdownDescription: "Global HSRP IPv6 address", + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "address": schema.StringAttribute{ + MarkdownDescription: "Set Global HSRP IPv6 address", + Computed: true, + }, + }, + }, + }, + "address_link_local_autoconfig_legacy_compatible": schema.BoolAttribute{ + MarkdownDescription: "Autoconfigure for Legacy compatibility (with IOS/NX-OS)", + Computed: true, + }, + "address_link_local_ipv6_address": schema.StringAttribute{ + MarkdownDescription: "HSRP IPv6 linklocal address", + Computed: true, + }, + }, + } +} + +func (d *RouterHSRPInterfaceAddressFamilyIPv6V1DataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + d.client = req.ProviderData.(*client.Client) +} + +func (d *RouterHSRPInterfaceAddressFamilyIPv6V1DataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var config RouterHSRPInterfaceAddressFamilyIPv6V1Data + + // 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_router_hsrp_interface_address_family_ipv6_v1_test.go b/internal/provider/data_source_iosxr_router_hsrp_interface_address_family_ipv6_v1_test.go new file mode 100644 index 00000000..5178a611 --- /dev/null +++ b/internal/provider/data_source_iosxr_router_hsrp_interface_address_family_ipv6_v1_test.go @@ -0,0 +1,91 @@ +// 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 TestAccDataSourceIosxrRouterHSRPInterfaceAddressFamilyIPv6V1(t *testing.T) { + var checks []resource.TestCheckFunc + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "name", "gp1")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "mac_address", "00:02:00:01:00:01")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "timers_hold_time", "10")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "timers_hold_time2", "20")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "timers_msec", "100")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "timers_msec2", "130")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "preempt_delay", "256")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "priority", "244")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "bfd_fast_detect_peer_ipv6", "fe80::240:d0ff:fe48:4672")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "bfd_fast_detect_peer_interface", "GigabitEthernet0/0/0/2")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "track_objects.0.object_name", "TOBJ1")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "track_objects.0.priority_decrement", "10")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "track_interfaces.0.track_name", "GigabitEthernet0/0/0/4")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "track_interfaces.0.priority_decrement", "244")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "address_link_local_autoconfig_legacy_compatible", "true")) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceIosxrRouterHSRPInterfaceAddressFamilyIPv6V1Config(), + Check: resource.ComposeTestCheckFunc(checks...), + }, + }, + }) +} + +func testAccDataSourceIosxrRouterHSRPInterfaceAddressFamilyIPv6V1Config() string { + config := `resource "iosxr_router_hsrp_interface_address_family_ipv6_v1" "test" {` + "\n" + config += ` delete_mode = "attributes"` + "\n" + config += ` interface_name = "GigabitEthernet0/0/0/1"` + "\n" + config += ` group_number_version_1_id = 135` + "\n" + config += ` name = "gp1"` + "\n" + config += ` mac_address = "00:02:00:01:00:01"` + "\n" + config += ` timers_hold_time = 10` + "\n" + config += ` timers_hold_time2 = 20` + "\n" + config += ` timers_msec = 100` + "\n" + config += ` timers_msec2 = 130` + "\n" + config += ` preempt_delay = 256` + "\n" + config += ` priority = 244` + "\n" + config += ` bfd_fast_detect_peer_ipv6 = "fe80::240:d0ff:fe48:4672"` + "\n" + config += ` bfd_fast_detect_peer_interface = "GigabitEthernet0/0/0/2"` + "\n" + config += ` track_objects = [{` + "\n" + config += ` object_name = "TOBJ1"` + "\n" + config += ` priority_decrement = 10` + "\n" + config += ` }]` + "\n" + config += ` track_interfaces = [{` + "\n" + config += ` track_name = "GigabitEthernet0/0/0/4"` + "\n" + config += ` priority_decrement = 244` + "\n" + config += ` }]` + "\n" + config += ` address_link_local_autoconfig_legacy_compatible = true` + "\n" + config += `}` + "\n" + + config += ` + data "iosxr_router_hsrp_interface_address_family_ipv6_v1" "test" { + interface_name = "GigabitEthernet0/0/0/1" + group_number_version_1_id = 135 + depends_on = [iosxr_router_hsrp_interface_address_family_ipv6_v1.test] + } + ` + return config +} diff --git a/internal/provider/data_source_iosxr_router_hsrp_interface_address_family_ipv6_v2.go b/internal/provider/data_source_iosxr_router_hsrp_interface_address_family_ipv6_v2.go new file mode 100644 index 00000000..aba69bf1 --- /dev/null +++ b/internal/provider/data_source_iosxr_router_hsrp_interface_address_family_ipv6_v2.go @@ -0,0 +1,202 @@ +// 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 = &RouterHSRPInterfaceAddressFamilyIPv6V2DataSource{} + _ datasource.DataSourceWithConfigure = &RouterHSRPInterfaceAddressFamilyIPv6V2DataSource{} +) + +func NewRouterHSRPInterfaceAddressFamilyIPv6V2DataSource() datasource.DataSource { + return &RouterHSRPInterfaceAddressFamilyIPv6V2DataSource{} +} + +type RouterHSRPInterfaceAddressFamilyIPv6V2DataSource struct { + client *client.Client +} + +func (d *RouterHSRPInterfaceAddressFamilyIPv6V2DataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_router_hsrp_interface_address_family_ipv6_v2" +} + +func (d *RouterHSRPInterfaceAddressFamilyIPv6V2DataSource) 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 Router HSRP Interface Address Family IPv6 V2 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, + }, + "interface_name": schema.StringAttribute{ + MarkdownDescription: "HSRP interface configuration subcommands", + Required: true, + }, + "group_number_version_2_id": schema.Int64Attribute{ + MarkdownDescription: "group number version 2", + Required: true, + }, + "name": schema.StringAttribute{ + MarkdownDescription: "MGO session name", + Computed: true, + }, + "mac_address": schema.StringAttribute{ + MarkdownDescription: "Use specified mac address for the virtual router", + Computed: true, + }, + "timers_hold_time": schema.Int64Attribute{ + MarkdownDescription: "Hold time in seconds", + Computed: true, + }, + "timers_hold_time2": schema.Int64Attribute{ + MarkdownDescription: "Hold time in seconds", + Computed: true, + }, + "timers_msec": schema.Int64Attribute{ + MarkdownDescription: "Specify hellotime in milliseconds", + Computed: true, + }, + "timers_msec2": schema.Int64Attribute{ + MarkdownDescription: "Specify hold time in milliseconds", + Computed: true, + }, + "preempt_delay": schema.Int64Attribute{ + MarkdownDescription: "Wait before preempting", + Computed: true, + }, + "priority": schema.Int64Attribute{ + MarkdownDescription: "Priority level", + Computed: true, + }, + "bfd_fast_detect_peer_ipv6": schema.StringAttribute{ + MarkdownDescription: "BFD peer interface IPv6 address", + Computed: true, + }, + "bfd_fast_detect_peer_interface": schema.StringAttribute{ + MarkdownDescription: "Select an interface over which to run BFD", + Computed: true, + }, + "track_objects": schema.ListNestedAttribute{ + MarkdownDescription: "Object tracking", + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "object_name": schema.StringAttribute{ + MarkdownDescription: "Object tracking", + Computed: true, + }, + "priority_decrement": schema.Int64Attribute{ + MarkdownDescription: "Priority decrement", + Computed: true, + }, + }, + }, + }, + "track_interfaces": schema.ListNestedAttribute{ + MarkdownDescription: "Configure tracking", + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "track_name": schema.StringAttribute{ + MarkdownDescription: "Configure tracking", + Computed: true, + }, + "priority_decrement": schema.Int64Attribute{ + MarkdownDescription: "Priority decrement", + Computed: true, + }, + }, + }, + }, + "address_globals": schema.ListNestedAttribute{ + MarkdownDescription: "Global HSRP IPv6 address", + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "address": schema.StringAttribute{ + MarkdownDescription: "Set Global HSRP IPv6 address", + Computed: true, + }, + }, + }, + }, + "address_link_local_autoconfig_legacy_compatible": schema.BoolAttribute{ + MarkdownDescription: "Autoconfigure for Legacy compatibility (with IOS/NX-OS)", + Computed: true, + }, + "address_link_local_ipv6_address": schema.StringAttribute{ + MarkdownDescription: "HSRP IPv6 linklocal address", + Computed: true, + }, + }, + } +} + +func (d *RouterHSRPInterfaceAddressFamilyIPv6V2DataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + d.client = req.ProviderData.(*client.Client) +} + +func (d *RouterHSRPInterfaceAddressFamilyIPv6V2DataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var config RouterHSRPInterfaceAddressFamilyIPv6V2Data + + // 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_router_hsrp_interface_address_family_ipv6_v2_test.go b/internal/provider/data_source_iosxr_router_hsrp_interface_address_family_ipv6_v2_test.go new file mode 100644 index 00000000..9f634b90 --- /dev/null +++ b/internal/provider/data_source_iosxr_router_hsrp_interface_address_family_ipv6_v2_test.go @@ -0,0 +1,95 @@ +// 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 TestAccDataSourceIosxrRouterHSRPInterfaceAddressFamilyIPv6V2(t *testing.T) { + var checks []resource.TestCheckFunc + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "name", "gp2")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "mac_address", "00:01:00:02:00:02")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "timers_hold_time", "10")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "timers_hold_time2", "20")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "timers_msec", "100")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "timers_msec2", "130")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "preempt_delay", "256")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "priority", "244")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "bfd_fast_detect_peer_ipv6", "fe80::240:d0ff:fe48:4672")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "bfd_fast_detect_peer_interface", "GigabitEthernet0/0/0/3")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "track_objects.0.object_name", "TOBJ2")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "track_objects.0.priority_decrement", "10")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "track_interfaces.0.track_name", "GigabitEthernet0/0/0/4")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "track_interfaces.0.priority_decrement", "244")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "address_globals.0.address", "2001:db8:cafe:2100::bad1:1010")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "address_link_local_autoconfig_legacy_compatible", "true")) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceIosxrRouterHSRPInterfaceAddressFamilyIPv6V2Config(), + Check: resource.ComposeTestCheckFunc(checks...), + }, + }, + }) +} + +func testAccDataSourceIosxrRouterHSRPInterfaceAddressFamilyIPv6V2Config() string { + config := `resource "iosxr_router_hsrp_interface_address_family_ipv6_v2" "test" {` + "\n" + config += ` delete_mode = "attributes"` + "\n" + config += ` interface_name = "GigabitEthernet0/0/0/2"` + "\n" + config += ` group_number_version_2_id = 4055` + "\n" + config += ` name = "gp2"` + "\n" + config += ` mac_address = "00:01:00:02:00:02"` + "\n" + config += ` timers_hold_time = 10` + "\n" + config += ` timers_hold_time2 = 20` + "\n" + config += ` timers_msec = 100` + "\n" + config += ` timers_msec2 = 130` + "\n" + config += ` preempt_delay = 256` + "\n" + config += ` priority = 244` + "\n" + config += ` bfd_fast_detect_peer_ipv6 = "fe80::240:d0ff:fe48:4672"` + "\n" + config += ` bfd_fast_detect_peer_interface = "GigabitEthernet0/0/0/3"` + "\n" + config += ` track_objects = [{` + "\n" + config += ` object_name = "TOBJ2"` + "\n" + config += ` priority_decrement = 10` + "\n" + config += ` }]` + "\n" + config += ` track_interfaces = [{` + "\n" + config += ` track_name = "GigabitEthernet0/0/0/4"` + "\n" + config += ` priority_decrement = 244` + "\n" + config += ` }]` + "\n" + config += ` address_globals = [{` + "\n" + config += ` address = "2001:db8:cafe:2100::bad1:1010"` + "\n" + config += ` }]` + "\n" + config += ` address_link_local_autoconfig_legacy_compatible = true` + "\n" + config += `}` + "\n" + + config += ` + data "iosxr_router_hsrp_interface_address_family_ipv6_v2" "test" { + interface_name = "GigabitEthernet0/0/0/2" + group_number_version_2_id = 4055 + depends_on = [iosxr_router_hsrp_interface_address_family_ipv6_v2.test] + } + ` + return config +} diff --git a/internal/provider/model_iosxr_router_hsrp_interface_address_family_ipv6_v1.go b/internal/provider/model_iosxr_router_hsrp_interface_address_family_ipv6_v1.go new file mode 100644 index 00000000..ef80775c --- /dev/null +++ b/internal/provider/model_iosxr_router_hsrp_interface_address_family_ipv6_v1.go @@ -0,0 +1,613 @@ +// 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 RouterHSRPInterfaceAddressFamilyIPv6V1 struct { + Device types.String `tfsdk:"device"` + Id types.String `tfsdk:"id"` + DeleteMode types.String `tfsdk:"delete_mode"` + InterfaceName types.String `tfsdk:"interface_name"` + GroupNumberVersion1Id types.Int64 `tfsdk:"group_number_version_1_id"` + Name types.String `tfsdk:"name"` + MacAddress types.String `tfsdk:"mac_address"` + TimersHoldTime types.Int64 `tfsdk:"timers_hold_time"` + TimersHoldTime2 types.Int64 `tfsdk:"timers_hold_time2"` + TimersMsec types.Int64 `tfsdk:"timers_msec"` + TimersMsec2 types.Int64 `tfsdk:"timers_msec2"` + PreemptDelay types.Int64 `tfsdk:"preempt_delay"` + Priority types.Int64 `tfsdk:"priority"` + BfdFastDetectPeerIpv6 types.String `tfsdk:"bfd_fast_detect_peer_ipv6"` + BfdFastDetectPeerInterface types.String `tfsdk:"bfd_fast_detect_peer_interface"` + TrackObjects []RouterHSRPInterfaceAddressFamilyIPv6V1TrackObjects `tfsdk:"track_objects"` + TrackInterfaces []RouterHSRPInterfaceAddressFamilyIPv6V1TrackInterfaces `tfsdk:"track_interfaces"` + AddressGlobals []RouterHSRPInterfaceAddressFamilyIPv6V1AddressGlobals `tfsdk:"address_globals"` + AddressLinkLocalAutoconfigLegacyCompatible types.Bool `tfsdk:"address_link_local_autoconfig_legacy_compatible"` + AddressLinkLocalIpv6Address types.String `tfsdk:"address_link_local_ipv6_address"` +} + +type RouterHSRPInterfaceAddressFamilyIPv6V1Data struct { + Device types.String `tfsdk:"device"` + Id types.String `tfsdk:"id"` + InterfaceName types.String `tfsdk:"interface_name"` + GroupNumberVersion1Id types.Int64 `tfsdk:"group_number_version_1_id"` + Name types.String `tfsdk:"name"` + MacAddress types.String `tfsdk:"mac_address"` + TimersHoldTime types.Int64 `tfsdk:"timers_hold_time"` + TimersHoldTime2 types.Int64 `tfsdk:"timers_hold_time2"` + TimersMsec types.Int64 `tfsdk:"timers_msec"` + TimersMsec2 types.Int64 `tfsdk:"timers_msec2"` + PreemptDelay types.Int64 `tfsdk:"preempt_delay"` + Priority types.Int64 `tfsdk:"priority"` + BfdFastDetectPeerIpv6 types.String `tfsdk:"bfd_fast_detect_peer_ipv6"` + BfdFastDetectPeerInterface types.String `tfsdk:"bfd_fast_detect_peer_interface"` + TrackObjects []RouterHSRPInterfaceAddressFamilyIPv6V1TrackObjects `tfsdk:"track_objects"` + TrackInterfaces []RouterHSRPInterfaceAddressFamilyIPv6V1TrackInterfaces `tfsdk:"track_interfaces"` + AddressGlobals []RouterHSRPInterfaceAddressFamilyIPv6V1AddressGlobals `tfsdk:"address_globals"` + AddressLinkLocalAutoconfigLegacyCompatible types.Bool `tfsdk:"address_link_local_autoconfig_legacy_compatible"` + AddressLinkLocalIpv6Address types.String `tfsdk:"address_link_local_ipv6_address"` +} +type RouterHSRPInterfaceAddressFamilyIPv6V1TrackObjects struct { + ObjectName types.String `tfsdk:"object_name"` + PriorityDecrement types.Int64 `tfsdk:"priority_decrement"` +} +type RouterHSRPInterfaceAddressFamilyIPv6V1TrackInterfaces struct { + TrackName types.String `tfsdk:"track_name"` + PriorityDecrement types.Int64 `tfsdk:"priority_decrement"` +} +type RouterHSRPInterfaceAddressFamilyIPv6V1AddressGlobals struct { + Address types.String `tfsdk:"address"` +} + +func (data RouterHSRPInterfaceAddressFamilyIPv6V1) getPath() string { + return fmt.Sprintf("Cisco-IOS-XR-um-router-hsrp-cfg:/router/hsrp/interfaces/interface[interface-name=%s]/address-family/ipv6/hsrp/group-number-version-1s/group-number-version-1[group-number-version-1-id=%v]", data.InterfaceName.ValueString(), data.GroupNumberVersion1Id.ValueInt64()) +} + +func (data RouterHSRPInterfaceAddressFamilyIPv6V1Data) getPath() string { + return fmt.Sprintf("Cisco-IOS-XR-um-router-hsrp-cfg:/router/hsrp/interfaces/interface[interface-name=%s]/address-family/ipv6/hsrp/group-number-version-1s/group-number-version-1[group-number-version-1-id=%v]", data.InterfaceName.ValueString(), data.GroupNumberVersion1Id.ValueInt64()) +} + +func (data RouterHSRPInterfaceAddressFamilyIPv6V1) toBody(ctx context.Context) string { + body := "{}" + if !data.GroupNumberVersion1Id.IsNull() && !data.GroupNumberVersion1Id.IsUnknown() { + body, _ = sjson.Set(body, "group-number-version-1-id", strconv.FormatInt(data.GroupNumberVersion1Id.ValueInt64(), 10)) + } + if !data.Name.IsNull() && !data.Name.IsUnknown() { + body, _ = sjson.Set(body, "name", data.Name.ValueString()) + } + if !data.MacAddress.IsNull() && !data.MacAddress.IsUnknown() { + body, _ = sjson.Set(body, "mac-address", data.MacAddress.ValueString()) + } + if !data.TimersHoldTime.IsNull() && !data.TimersHoldTime.IsUnknown() { + body, _ = sjson.Set(body, "timers.hold-time", strconv.FormatInt(data.TimersHoldTime.ValueInt64(), 10)) + } + if !data.TimersHoldTime2.IsNull() && !data.TimersHoldTime2.IsUnknown() { + body, _ = sjson.Set(body, "timers.hold-time2", strconv.FormatInt(data.TimersHoldTime2.ValueInt64(), 10)) + } + if !data.TimersMsec.IsNull() && !data.TimersMsec.IsUnknown() { + body, _ = sjson.Set(body, "timers.msec", strconv.FormatInt(data.TimersMsec.ValueInt64(), 10)) + } + if !data.TimersMsec2.IsNull() && !data.TimersMsec2.IsUnknown() { + body, _ = sjson.Set(body, "timers.msec2", strconv.FormatInt(data.TimersMsec2.ValueInt64(), 10)) + } + if !data.PreemptDelay.IsNull() && !data.PreemptDelay.IsUnknown() { + body, _ = sjson.Set(body, "preempt.delay", strconv.FormatInt(data.PreemptDelay.ValueInt64(), 10)) + } + if !data.Priority.IsNull() && !data.Priority.IsUnknown() { + body, _ = sjson.Set(body, "priority", strconv.FormatInt(data.Priority.ValueInt64(), 10)) + } + if !data.BfdFastDetectPeerIpv6.IsNull() && !data.BfdFastDetectPeerIpv6.IsUnknown() { + body, _ = sjson.Set(body, "bfd.fast-detect.peer.ipv6", data.BfdFastDetectPeerIpv6.ValueString()) + } + if !data.BfdFastDetectPeerInterface.IsNull() && !data.BfdFastDetectPeerInterface.IsUnknown() { + body, _ = sjson.Set(body, "bfd.fast-detect.peer.interface", data.BfdFastDetectPeerInterface.ValueString()) + } + if !data.AddressLinkLocalAutoconfigLegacyCompatible.IsNull() && !data.AddressLinkLocalAutoconfigLegacyCompatible.IsUnknown() { + if data.AddressLinkLocalAutoconfigLegacyCompatible.ValueBool() { + body, _ = sjson.Set(body, "address.link-local.autoconfig.legacy-compatible", map[string]string{}) + } + } + if !data.AddressLinkLocalIpv6Address.IsNull() && !data.AddressLinkLocalIpv6Address.IsUnknown() { + body, _ = sjson.Set(body, "address.link-local.ipv6-address", data.AddressLinkLocalIpv6Address.ValueString()) + } + if len(data.TrackObjects) > 0 { + body, _ = sjson.Set(body, "track-objects.track-object", []interface{}{}) + for index, item := range data.TrackObjects { + if !item.ObjectName.IsNull() && !item.ObjectName.IsUnknown() { + body, _ = sjson.Set(body, "track-objects.track-object"+"."+strconv.Itoa(index)+"."+"object-name", item.ObjectName.ValueString()) + } + if !item.PriorityDecrement.IsNull() && !item.PriorityDecrement.IsUnknown() { + body, _ = sjson.Set(body, "track-objects.track-object"+"."+strconv.Itoa(index)+"."+"priority-decrement", strconv.FormatInt(item.PriorityDecrement.ValueInt64(), 10)) + } + } + } + if len(data.TrackInterfaces) > 0 { + body, _ = sjson.Set(body, "track-interfaces.track-interface", []interface{}{}) + for index, item := range data.TrackInterfaces { + if !item.TrackName.IsNull() && !item.TrackName.IsUnknown() { + body, _ = sjson.Set(body, "track-interfaces.track-interface"+"."+strconv.Itoa(index)+"."+"track-name", item.TrackName.ValueString()) + } + if !item.PriorityDecrement.IsNull() && !item.PriorityDecrement.IsUnknown() { + body, _ = sjson.Set(body, "track-interfaces.track-interface"+"."+strconv.Itoa(index)+"."+"priority-decrement", strconv.FormatInt(item.PriorityDecrement.ValueInt64(), 10)) + } + } + } + if len(data.AddressGlobals) > 0 { + body, _ = sjson.Set(body, "address.globals.global", []interface{}{}) + for index, item := range data.AddressGlobals { + if !item.Address.IsNull() && !item.Address.IsUnknown() { + body, _ = sjson.Set(body, "address.globals.global"+"."+strconv.Itoa(index)+"."+"address", item.Address.ValueString()) + } + } + } + return body +} + +func (data *RouterHSRPInterfaceAddressFamilyIPv6V1) updateFromBody(ctx context.Context, res []byte) { + if value := gjson.GetBytes(res, "name"); value.Exists() && !data.Name.IsNull() { + data.Name = types.StringValue(value.String()) + } else { + data.Name = types.StringNull() + } + if value := gjson.GetBytes(res, "mac-address"); value.Exists() && !data.MacAddress.IsNull() { + data.MacAddress = types.StringValue(value.String()) + } else { + data.MacAddress = types.StringNull() + } + if value := gjson.GetBytes(res, "timers.hold-time"); value.Exists() && !data.TimersHoldTime.IsNull() { + data.TimersHoldTime = types.Int64Value(value.Int()) + } else { + data.TimersHoldTime = types.Int64Null() + } + if value := gjson.GetBytes(res, "timers.hold-time2"); value.Exists() && !data.TimersHoldTime2.IsNull() { + data.TimersHoldTime2 = types.Int64Value(value.Int()) + } else { + data.TimersHoldTime2 = types.Int64Null() + } + if value := gjson.GetBytes(res, "timers.msec"); value.Exists() && !data.TimersMsec.IsNull() { + data.TimersMsec = types.Int64Value(value.Int()) + } else { + data.TimersMsec = types.Int64Null() + } + if value := gjson.GetBytes(res, "timers.msec2"); value.Exists() && !data.TimersMsec2.IsNull() { + data.TimersMsec2 = types.Int64Value(value.Int()) + } else { + data.TimersMsec2 = types.Int64Null() + } + if value := gjson.GetBytes(res, "preempt.delay"); value.Exists() && !data.PreemptDelay.IsNull() { + data.PreemptDelay = types.Int64Value(value.Int()) + } else { + data.PreemptDelay = types.Int64Null() + } + if value := gjson.GetBytes(res, "priority"); value.Exists() && !data.Priority.IsNull() { + data.Priority = types.Int64Value(value.Int()) + } else { + data.Priority = types.Int64Null() + } + if value := gjson.GetBytes(res, "bfd.fast-detect.peer.ipv6"); value.Exists() && !data.BfdFastDetectPeerIpv6.IsNull() { + data.BfdFastDetectPeerIpv6 = types.StringValue(value.String()) + } else { + data.BfdFastDetectPeerIpv6 = types.StringNull() + } + if value := gjson.GetBytes(res, "bfd.fast-detect.peer.interface"); value.Exists() && !data.BfdFastDetectPeerInterface.IsNull() { + data.BfdFastDetectPeerInterface = types.StringValue(value.String()) + } else { + data.BfdFastDetectPeerInterface = types.StringNull() + } + for i := range data.TrackObjects { + keys := [...]string{"object-name"} + keyValues := [...]string{data.TrackObjects[i].ObjectName.ValueString()} + + var r gjson.Result + gjson.GetBytes(res, "track-objects.track-object").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("object-name"); value.Exists() && !data.TrackObjects[i].ObjectName.IsNull() { + data.TrackObjects[i].ObjectName = types.StringValue(value.String()) + } else { + data.TrackObjects[i].ObjectName = types.StringNull() + } + if value := r.Get("priority-decrement"); value.Exists() && !data.TrackObjects[i].PriorityDecrement.IsNull() { + data.TrackObjects[i].PriorityDecrement = types.Int64Value(value.Int()) + } else { + data.TrackObjects[i].PriorityDecrement = types.Int64Null() + } + } + for i := range data.TrackInterfaces { + keys := [...]string{"track-name"} + keyValues := [...]string{data.TrackInterfaces[i].TrackName.ValueString()} + + var r gjson.Result + gjson.GetBytes(res, "track-interfaces.track-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("track-name"); value.Exists() && !data.TrackInterfaces[i].TrackName.IsNull() { + data.TrackInterfaces[i].TrackName = types.StringValue(value.String()) + } else { + data.TrackInterfaces[i].TrackName = types.StringNull() + } + if value := r.Get("priority-decrement"); value.Exists() && !data.TrackInterfaces[i].PriorityDecrement.IsNull() { + data.TrackInterfaces[i].PriorityDecrement = types.Int64Value(value.Int()) + } else { + data.TrackInterfaces[i].PriorityDecrement = types.Int64Null() + } + } + for i := range data.AddressGlobals { + keys := [...]string{"address"} + keyValues := [...]string{data.AddressGlobals[i].Address.ValueString()} + + var r gjson.Result + gjson.GetBytes(res, "address.globals.global").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("address"); value.Exists() && !data.AddressGlobals[i].Address.IsNull() { + data.AddressGlobals[i].Address = types.StringValue(value.String()) + } else { + data.AddressGlobals[i].Address = types.StringNull() + } + } + if value := gjson.GetBytes(res, "address.link-local.autoconfig.legacy-compatible"); !data.AddressLinkLocalAutoconfigLegacyCompatible.IsNull() { + if value.Exists() { + data.AddressLinkLocalAutoconfigLegacyCompatible = types.BoolValue(true) + } else { + data.AddressLinkLocalAutoconfigLegacyCompatible = types.BoolValue(false) + } + } else { + data.AddressLinkLocalAutoconfigLegacyCompatible = types.BoolNull() + } + if value := gjson.GetBytes(res, "address.link-local.ipv6-address"); value.Exists() && !data.AddressLinkLocalIpv6Address.IsNull() { + data.AddressLinkLocalIpv6Address = types.StringValue(value.String()) + } else { + data.AddressLinkLocalIpv6Address = types.StringNull() + } +} + +func (data *RouterHSRPInterfaceAddressFamilyIPv6V1Data) fromBody(ctx context.Context, res []byte) { + if value := gjson.GetBytes(res, "name"); value.Exists() { + data.Name = types.StringValue(value.String()) + } + if value := gjson.GetBytes(res, "mac-address"); value.Exists() { + data.MacAddress = types.StringValue(value.String()) + } + if value := gjson.GetBytes(res, "timers.hold-time"); value.Exists() { + data.TimersHoldTime = types.Int64Value(value.Int()) + } + if value := gjson.GetBytes(res, "timers.hold-time2"); value.Exists() { + data.TimersHoldTime2 = types.Int64Value(value.Int()) + } + if value := gjson.GetBytes(res, "timers.msec"); value.Exists() { + data.TimersMsec = types.Int64Value(value.Int()) + } + if value := gjson.GetBytes(res, "timers.msec2"); value.Exists() { + data.TimersMsec2 = types.Int64Value(value.Int()) + } + if value := gjson.GetBytes(res, "preempt.delay"); value.Exists() { + data.PreemptDelay = types.Int64Value(value.Int()) + } + if value := gjson.GetBytes(res, "priority"); value.Exists() { + data.Priority = types.Int64Value(value.Int()) + } + if value := gjson.GetBytes(res, "bfd.fast-detect.peer.ipv6"); value.Exists() { + data.BfdFastDetectPeerIpv6 = types.StringValue(value.String()) + } + if value := gjson.GetBytes(res, "bfd.fast-detect.peer.interface"); value.Exists() { + data.BfdFastDetectPeerInterface = types.StringValue(value.String()) + } + if value := gjson.GetBytes(res, "track-objects.track-object"); value.Exists() { + data.TrackObjects = make([]RouterHSRPInterfaceAddressFamilyIPv6V1TrackObjects, 0) + value.ForEach(func(k, v gjson.Result) bool { + item := RouterHSRPInterfaceAddressFamilyIPv6V1TrackObjects{} + if cValue := v.Get("object-name"); cValue.Exists() { + item.ObjectName = types.StringValue(cValue.String()) + } + if cValue := v.Get("priority-decrement"); cValue.Exists() { + item.PriorityDecrement = types.Int64Value(cValue.Int()) + } + data.TrackObjects = append(data.TrackObjects, item) + return true + }) + } + if value := gjson.GetBytes(res, "track-interfaces.track-interface"); value.Exists() { + data.TrackInterfaces = make([]RouterHSRPInterfaceAddressFamilyIPv6V1TrackInterfaces, 0) + value.ForEach(func(k, v gjson.Result) bool { + item := RouterHSRPInterfaceAddressFamilyIPv6V1TrackInterfaces{} + if cValue := v.Get("track-name"); cValue.Exists() { + item.TrackName = types.StringValue(cValue.String()) + } + if cValue := v.Get("priority-decrement"); cValue.Exists() { + item.PriorityDecrement = types.Int64Value(cValue.Int()) + } + data.TrackInterfaces = append(data.TrackInterfaces, item) + return true + }) + } + if value := gjson.GetBytes(res, "address.globals.global"); value.Exists() { + data.AddressGlobals = make([]RouterHSRPInterfaceAddressFamilyIPv6V1AddressGlobals, 0) + value.ForEach(func(k, v gjson.Result) bool { + item := RouterHSRPInterfaceAddressFamilyIPv6V1AddressGlobals{} + if cValue := v.Get("address"); cValue.Exists() { + item.Address = types.StringValue(cValue.String()) + } + data.AddressGlobals = append(data.AddressGlobals, item) + return true + }) + } + if value := gjson.GetBytes(res, "address.link-local.autoconfig.legacy-compatible"); value.Exists() { + data.AddressLinkLocalAutoconfigLegacyCompatible = types.BoolValue(true) + } else { + data.AddressLinkLocalAutoconfigLegacyCompatible = types.BoolValue(false) + } + if value := gjson.GetBytes(res, "address.link-local.ipv6-address"); value.Exists() { + data.AddressLinkLocalIpv6Address = types.StringValue(value.String()) + } +} + +func (data *RouterHSRPInterfaceAddressFamilyIPv6V1) getDeletedListItems(ctx context.Context, state RouterHSRPInterfaceAddressFamilyIPv6V1) []string { + deletedListItems := make([]string, 0) + for i := range state.TrackObjects { + keys := [...]string{"object-name"} + stateKeyValues := [...]string{state.TrackObjects[i].ObjectName.ValueString()} + + emptyKeys := true + if !reflect.ValueOf(state.TrackObjects[i].ObjectName.ValueString()).IsZero() { + emptyKeys = false + } + if emptyKeys { + continue + } + + found := false + for j := range data.TrackObjects { + found = true + if state.TrackObjects[i].ObjectName.ValueString() != data.TrackObjects[j].ObjectName.ValueString() { + found = false + } + if found { + break + } + } + if !found { + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + stateKeyValues[ki] + "]" + } + deletedListItems = append(deletedListItems, fmt.Sprintf("%v/track-objects/track-object%v", state.getPath(), keyString)) + } + } + for i := range state.TrackInterfaces { + keys := [...]string{"track-name"} + stateKeyValues := [...]string{state.TrackInterfaces[i].TrackName.ValueString()} + + emptyKeys := true + if !reflect.ValueOf(state.TrackInterfaces[i].TrackName.ValueString()).IsZero() { + emptyKeys = false + } + if emptyKeys { + continue + } + + found := false + for j := range data.TrackInterfaces { + found = true + if state.TrackInterfaces[i].TrackName.ValueString() != data.TrackInterfaces[j].TrackName.ValueString() { + found = false + } + if found { + break + } + } + if !found { + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + stateKeyValues[ki] + "]" + } + deletedListItems = append(deletedListItems, fmt.Sprintf("%v/track-interfaces/track-interface%v", state.getPath(), keyString)) + } + } + for i := range state.AddressGlobals { + keys := [...]string{"address"} + stateKeyValues := [...]string{state.AddressGlobals[i].Address.ValueString()} + + emptyKeys := true + if !reflect.ValueOf(state.AddressGlobals[i].Address.ValueString()).IsZero() { + emptyKeys = false + } + if emptyKeys { + continue + } + + found := false + for j := range data.AddressGlobals { + found = true + if state.AddressGlobals[i].Address.ValueString() != data.AddressGlobals[j].Address.ValueString() { + found = false + } + if found { + break + } + } + if !found { + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + stateKeyValues[ki] + "]" + } + deletedListItems = append(deletedListItems, fmt.Sprintf("%v/address/globals/global%v", state.getPath(), keyString)) + } + } + return deletedListItems +} + +func (data *RouterHSRPInterfaceAddressFamilyIPv6V1) getEmptyLeafsDelete(ctx context.Context) []string { + emptyLeafsDelete := make([]string, 0) + for i := range data.TrackObjects { + keys := [...]string{"object-name"} + keyValues := [...]string{data.TrackObjects[i].ObjectName.ValueString()} + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]" + } + } + for i := range data.TrackInterfaces { + keys := [...]string{"track-name"} + keyValues := [...]string{data.TrackInterfaces[i].TrackName.ValueString()} + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]" + } + } + for i := range data.AddressGlobals { + keys := [...]string{"address"} + keyValues := [...]string{data.AddressGlobals[i].Address.ValueString()} + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]" + } + } + if !data.AddressLinkLocalAutoconfigLegacyCompatible.IsNull() && !data.AddressLinkLocalAutoconfigLegacyCompatible.ValueBool() { + emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/address/link-local/autoconfig/legacy-compatible", data.getPath())) + } + return emptyLeafsDelete +} + +func (data *RouterHSRPInterfaceAddressFamilyIPv6V1) getDeletePaths(ctx context.Context) []string { + var deletePaths []string + if !data.Name.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/name", data.getPath())) + } + if !data.MacAddress.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/mac-address", data.getPath())) + } + if !data.TimersHoldTime.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/timers/hold-time", data.getPath())) + } + if !data.TimersHoldTime2.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/timers/hold-time2", data.getPath())) + } + if !data.TimersMsec.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/timers/msec", data.getPath())) + } + if !data.TimersMsec2.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/timers/msec2", data.getPath())) + } + if !data.PreemptDelay.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/preempt/delay", data.getPath())) + } + if !data.Priority.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/priority", data.getPath())) + } + if !data.BfdFastDetectPeerIpv6.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/bfd/fast-detect/peer/ipv6", data.getPath())) + } + if !data.BfdFastDetectPeerInterface.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/bfd/fast-detect/peer/interface", data.getPath())) + } + for i := range data.TrackObjects { + keys := [...]string{"object-name"} + keyValues := [...]string{data.TrackObjects[i].ObjectName.ValueString()} + + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]" + } + deletePaths = append(deletePaths, fmt.Sprintf("%v/track-objects/track-object%v", data.getPath(), keyString)) + } + for i := range data.TrackInterfaces { + keys := [...]string{"track-name"} + keyValues := [...]string{data.TrackInterfaces[i].TrackName.ValueString()} + + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]" + } + deletePaths = append(deletePaths, fmt.Sprintf("%v/track-interfaces/track-interface%v", data.getPath(), keyString)) + } + for i := range data.AddressGlobals { + keys := [...]string{"address"} + keyValues := [...]string{data.AddressGlobals[i].Address.ValueString()} + + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]" + } + deletePaths = append(deletePaths, fmt.Sprintf("%v/address/globals/global%v", data.getPath(), keyString)) + } + if !data.AddressLinkLocalAutoconfigLegacyCompatible.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/address/link-local/autoconfig/legacy-compatible", data.getPath())) + } + if !data.AddressLinkLocalIpv6Address.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/address/link-local/ipv6-address", data.getPath())) + } + return deletePaths +} diff --git a/internal/provider/model_iosxr_router_hsrp_interface_address_family_ipv6_v2.go b/internal/provider/model_iosxr_router_hsrp_interface_address_family_ipv6_v2.go new file mode 100644 index 00000000..00328f2b --- /dev/null +++ b/internal/provider/model_iosxr_router_hsrp_interface_address_family_ipv6_v2.go @@ -0,0 +1,613 @@ +// 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 RouterHSRPInterfaceAddressFamilyIPv6V2 struct { + Device types.String `tfsdk:"device"` + Id types.String `tfsdk:"id"` + DeleteMode types.String `tfsdk:"delete_mode"` + InterfaceName types.String `tfsdk:"interface_name"` + GroupNumberVersion2Id types.Int64 `tfsdk:"group_number_version_2_id"` + Name types.String `tfsdk:"name"` + MacAddress types.String `tfsdk:"mac_address"` + TimersHoldTime types.Int64 `tfsdk:"timers_hold_time"` + TimersHoldTime2 types.Int64 `tfsdk:"timers_hold_time2"` + TimersMsec types.Int64 `tfsdk:"timers_msec"` + TimersMsec2 types.Int64 `tfsdk:"timers_msec2"` + PreemptDelay types.Int64 `tfsdk:"preempt_delay"` + Priority types.Int64 `tfsdk:"priority"` + BfdFastDetectPeerIpv6 types.String `tfsdk:"bfd_fast_detect_peer_ipv6"` + BfdFastDetectPeerInterface types.String `tfsdk:"bfd_fast_detect_peer_interface"` + TrackObjects []RouterHSRPInterfaceAddressFamilyIPv6V2TrackObjects `tfsdk:"track_objects"` + TrackInterfaces []RouterHSRPInterfaceAddressFamilyIPv6V2TrackInterfaces `tfsdk:"track_interfaces"` + AddressGlobals []RouterHSRPInterfaceAddressFamilyIPv6V2AddressGlobals `tfsdk:"address_globals"` + AddressLinkLocalAutoconfigLegacyCompatible types.Bool `tfsdk:"address_link_local_autoconfig_legacy_compatible"` + AddressLinkLocalIpv6Address types.String `tfsdk:"address_link_local_ipv6_address"` +} + +type RouterHSRPInterfaceAddressFamilyIPv6V2Data struct { + Device types.String `tfsdk:"device"` + Id types.String `tfsdk:"id"` + InterfaceName types.String `tfsdk:"interface_name"` + GroupNumberVersion2Id types.Int64 `tfsdk:"group_number_version_2_id"` + Name types.String `tfsdk:"name"` + MacAddress types.String `tfsdk:"mac_address"` + TimersHoldTime types.Int64 `tfsdk:"timers_hold_time"` + TimersHoldTime2 types.Int64 `tfsdk:"timers_hold_time2"` + TimersMsec types.Int64 `tfsdk:"timers_msec"` + TimersMsec2 types.Int64 `tfsdk:"timers_msec2"` + PreemptDelay types.Int64 `tfsdk:"preempt_delay"` + Priority types.Int64 `tfsdk:"priority"` + BfdFastDetectPeerIpv6 types.String `tfsdk:"bfd_fast_detect_peer_ipv6"` + BfdFastDetectPeerInterface types.String `tfsdk:"bfd_fast_detect_peer_interface"` + TrackObjects []RouterHSRPInterfaceAddressFamilyIPv6V2TrackObjects `tfsdk:"track_objects"` + TrackInterfaces []RouterHSRPInterfaceAddressFamilyIPv6V2TrackInterfaces `tfsdk:"track_interfaces"` + AddressGlobals []RouterHSRPInterfaceAddressFamilyIPv6V2AddressGlobals `tfsdk:"address_globals"` + AddressLinkLocalAutoconfigLegacyCompatible types.Bool `tfsdk:"address_link_local_autoconfig_legacy_compatible"` + AddressLinkLocalIpv6Address types.String `tfsdk:"address_link_local_ipv6_address"` +} +type RouterHSRPInterfaceAddressFamilyIPv6V2TrackObjects struct { + ObjectName types.String `tfsdk:"object_name"` + PriorityDecrement types.Int64 `tfsdk:"priority_decrement"` +} +type RouterHSRPInterfaceAddressFamilyIPv6V2TrackInterfaces struct { + TrackName types.String `tfsdk:"track_name"` + PriorityDecrement types.Int64 `tfsdk:"priority_decrement"` +} +type RouterHSRPInterfaceAddressFamilyIPv6V2AddressGlobals struct { + Address types.String `tfsdk:"address"` +} + +func (data RouterHSRPInterfaceAddressFamilyIPv6V2) getPath() string { + return fmt.Sprintf("Cisco-IOS-XR-um-router-hsrp-cfg:/router/hsrp/interfaces/interface[interface-name=%s]/address-family/ipv6/hsrp/group-number-version-2s/group-number-version-2[group-number-version-2-id=%v]", data.InterfaceName.ValueString(), data.GroupNumberVersion2Id.ValueInt64()) +} + +func (data RouterHSRPInterfaceAddressFamilyIPv6V2Data) getPath() string { + return fmt.Sprintf("Cisco-IOS-XR-um-router-hsrp-cfg:/router/hsrp/interfaces/interface[interface-name=%s]/address-family/ipv6/hsrp/group-number-version-2s/group-number-version-2[group-number-version-2-id=%v]", data.InterfaceName.ValueString(), data.GroupNumberVersion2Id.ValueInt64()) +} + +func (data RouterHSRPInterfaceAddressFamilyIPv6V2) toBody(ctx context.Context) string { + body := "{}" + if !data.GroupNumberVersion2Id.IsNull() && !data.GroupNumberVersion2Id.IsUnknown() { + body, _ = sjson.Set(body, "group-number-version-2-id", strconv.FormatInt(data.GroupNumberVersion2Id.ValueInt64(), 10)) + } + if !data.Name.IsNull() && !data.Name.IsUnknown() { + body, _ = sjson.Set(body, "name", data.Name.ValueString()) + } + if !data.MacAddress.IsNull() && !data.MacAddress.IsUnknown() { + body, _ = sjson.Set(body, "mac-address", data.MacAddress.ValueString()) + } + if !data.TimersHoldTime.IsNull() && !data.TimersHoldTime.IsUnknown() { + body, _ = sjson.Set(body, "timers.hold-time", strconv.FormatInt(data.TimersHoldTime.ValueInt64(), 10)) + } + if !data.TimersHoldTime2.IsNull() && !data.TimersHoldTime2.IsUnknown() { + body, _ = sjson.Set(body, "timers.hold-time2", strconv.FormatInt(data.TimersHoldTime2.ValueInt64(), 10)) + } + if !data.TimersMsec.IsNull() && !data.TimersMsec.IsUnknown() { + body, _ = sjson.Set(body, "timers.msec", strconv.FormatInt(data.TimersMsec.ValueInt64(), 10)) + } + if !data.TimersMsec2.IsNull() && !data.TimersMsec2.IsUnknown() { + body, _ = sjson.Set(body, "timers.msec2", strconv.FormatInt(data.TimersMsec2.ValueInt64(), 10)) + } + if !data.PreemptDelay.IsNull() && !data.PreemptDelay.IsUnknown() { + body, _ = sjson.Set(body, "preempt.delay", strconv.FormatInt(data.PreemptDelay.ValueInt64(), 10)) + } + if !data.Priority.IsNull() && !data.Priority.IsUnknown() { + body, _ = sjson.Set(body, "priority", strconv.FormatInt(data.Priority.ValueInt64(), 10)) + } + if !data.BfdFastDetectPeerIpv6.IsNull() && !data.BfdFastDetectPeerIpv6.IsUnknown() { + body, _ = sjson.Set(body, "bfd.fast-detect.peer.ipv6", data.BfdFastDetectPeerIpv6.ValueString()) + } + if !data.BfdFastDetectPeerInterface.IsNull() && !data.BfdFastDetectPeerInterface.IsUnknown() { + body, _ = sjson.Set(body, "bfd.fast-detect.peer.interface", data.BfdFastDetectPeerInterface.ValueString()) + } + if !data.AddressLinkLocalAutoconfigLegacyCompatible.IsNull() && !data.AddressLinkLocalAutoconfigLegacyCompatible.IsUnknown() { + if data.AddressLinkLocalAutoconfigLegacyCompatible.ValueBool() { + body, _ = sjson.Set(body, "address.link-local.autoconfig.legacy-compatible", map[string]string{}) + } + } + if !data.AddressLinkLocalIpv6Address.IsNull() && !data.AddressLinkLocalIpv6Address.IsUnknown() { + body, _ = sjson.Set(body, "address.link-local.ipv6-address", data.AddressLinkLocalIpv6Address.ValueString()) + } + if len(data.TrackObjects) > 0 { + body, _ = sjson.Set(body, "track-objects.track-object", []interface{}{}) + for index, item := range data.TrackObjects { + if !item.ObjectName.IsNull() && !item.ObjectName.IsUnknown() { + body, _ = sjson.Set(body, "track-objects.track-object"+"."+strconv.Itoa(index)+"."+"object-name", item.ObjectName.ValueString()) + } + if !item.PriorityDecrement.IsNull() && !item.PriorityDecrement.IsUnknown() { + body, _ = sjson.Set(body, "track-objects.track-object"+"."+strconv.Itoa(index)+"."+"priority-decrement", strconv.FormatInt(item.PriorityDecrement.ValueInt64(), 10)) + } + } + } + if len(data.TrackInterfaces) > 0 { + body, _ = sjson.Set(body, "track-interfaces.track-interface", []interface{}{}) + for index, item := range data.TrackInterfaces { + if !item.TrackName.IsNull() && !item.TrackName.IsUnknown() { + body, _ = sjson.Set(body, "track-interfaces.track-interface"+"."+strconv.Itoa(index)+"."+"track-name", item.TrackName.ValueString()) + } + if !item.PriorityDecrement.IsNull() && !item.PriorityDecrement.IsUnknown() { + body, _ = sjson.Set(body, "track-interfaces.track-interface"+"."+strconv.Itoa(index)+"."+"priority-decrement", strconv.FormatInt(item.PriorityDecrement.ValueInt64(), 10)) + } + } + } + if len(data.AddressGlobals) > 0 { + body, _ = sjson.Set(body, "address.globals.global", []interface{}{}) + for index, item := range data.AddressGlobals { + if !item.Address.IsNull() && !item.Address.IsUnknown() { + body, _ = sjson.Set(body, "address.globals.global"+"."+strconv.Itoa(index)+"."+"address", item.Address.ValueString()) + } + } + } + return body +} + +func (data *RouterHSRPInterfaceAddressFamilyIPv6V2) updateFromBody(ctx context.Context, res []byte) { + if value := gjson.GetBytes(res, "name"); value.Exists() && !data.Name.IsNull() { + data.Name = types.StringValue(value.String()) + } else { + data.Name = types.StringNull() + } + if value := gjson.GetBytes(res, "mac-address"); value.Exists() && !data.MacAddress.IsNull() { + data.MacAddress = types.StringValue(value.String()) + } else { + data.MacAddress = types.StringNull() + } + if value := gjson.GetBytes(res, "timers.hold-time"); value.Exists() && !data.TimersHoldTime.IsNull() { + data.TimersHoldTime = types.Int64Value(value.Int()) + } else { + data.TimersHoldTime = types.Int64Null() + } + if value := gjson.GetBytes(res, "timers.hold-time2"); value.Exists() && !data.TimersHoldTime2.IsNull() { + data.TimersHoldTime2 = types.Int64Value(value.Int()) + } else { + data.TimersHoldTime2 = types.Int64Null() + } + if value := gjson.GetBytes(res, "timers.msec"); value.Exists() && !data.TimersMsec.IsNull() { + data.TimersMsec = types.Int64Value(value.Int()) + } else { + data.TimersMsec = types.Int64Null() + } + if value := gjson.GetBytes(res, "timers.msec2"); value.Exists() && !data.TimersMsec2.IsNull() { + data.TimersMsec2 = types.Int64Value(value.Int()) + } else { + data.TimersMsec2 = types.Int64Null() + } + if value := gjson.GetBytes(res, "preempt.delay"); value.Exists() && !data.PreemptDelay.IsNull() { + data.PreemptDelay = types.Int64Value(value.Int()) + } else { + data.PreemptDelay = types.Int64Null() + } + if value := gjson.GetBytes(res, "priority"); value.Exists() && !data.Priority.IsNull() { + data.Priority = types.Int64Value(value.Int()) + } else { + data.Priority = types.Int64Null() + } + if value := gjson.GetBytes(res, "bfd.fast-detect.peer.ipv6"); value.Exists() && !data.BfdFastDetectPeerIpv6.IsNull() { + data.BfdFastDetectPeerIpv6 = types.StringValue(value.String()) + } else { + data.BfdFastDetectPeerIpv6 = types.StringNull() + } + if value := gjson.GetBytes(res, "bfd.fast-detect.peer.interface"); value.Exists() && !data.BfdFastDetectPeerInterface.IsNull() { + data.BfdFastDetectPeerInterface = types.StringValue(value.String()) + } else { + data.BfdFastDetectPeerInterface = types.StringNull() + } + for i := range data.TrackObjects { + keys := [...]string{"object-name"} + keyValues := [...]string{data.TrackObjects[i].ObjectName.ValueString()} + + var r gjson.Result + gjson.GetBytes(res, "track-objects.track-object").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("object-name"); value.Exists() && !data.TrackObjects[i].ObjectName.IsNull() { + data.TrackObjects[i].ObjectName = types.StringValue(value.String()) + } else { + data.TrackObjects[i].ObjectName = types.StringNull() + } + if value := r.Get("priority-decrement"); value.Exists() && !data.TrackObjects[i].PriorityDecrement.IsNull() { + data.TrackObjects[i].PriorityDecrement = types.Int64Value(value.Int()) + } else { + data.TrackObjects[i].PriorityDecrement = types.Int64Null() + } + } + for i := range data.TrackInterfaces { + keys := [...]string{"track-name"} + keyValues := [...]string{data.TrackInterfaces[i].TrackName.ValueString()} + + var r gjson.Result + gjson.GetBytes(res, "track-interfaces.track-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("track-name"); value.Exists() && !data.TrackInterfaces[i].TrackName.IsNull() { + data.TrackInterfaces[i].TrackName = types.StringValue(value.String()) + } else { + data.TrackInterfaces[i].TrackName = types.StringNull() + } + if value := r.Get("priority-decrement"); value.Exists() && !data.TrackInterfaces[i].PriorityDecrement.IsNull() { + data.TrackInterfaces[i].PriorityDecrement = types.Int64Value(value.Int()) + } else { + data.TrackInterfaces[i].PriorityDecrement = types.Int64Null() + } + } + for i := range data.AddressGlobals { + keys := [...]string{"address"} + keyValues := [...]string{data.AddressGlobals[i].Address.ValueString()} + + var r gjson.Result + gjson.GetBytes(res, "address.globals.global").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("address"); value.Exists() && !data.AddressGlobals[i].Address.IsNull() { + data.AddressGlobals[i].Address = types.StringValue(value.String()) + } else { + data.AddressGlobals[i].Address = types.StringNull() + } + } + if value := gjson.GetBytes(res, "address.link-local.autoconfig.legacy-compatible"); !data.AddressLinkLocalAutoconfigLegacyCompatible.IsNull() { + if value.Exists() { + data.AddressLinkLocalAutoconfigLegacyCompatible = types.BoolValue(true) + } else { + data.AddressLinkLocalAutoconfigLegacyCompatible = types.BoolValue(false) + } + } else { + data.AddressLinkLocalAutoconfigLegacyCompatible = types.BoolNull() + } + if value := gjson.GetBytes(res, "address.link-local.ipv6-address"); value.Exists() && !data.AddressLinkLocalIpv6Address.IsNull() { + data.AddressLinkLocalIpv6Address = types.StringValue(value.String()) + } else { + data.AddressLinkLocalIpv6Address = types.StringNull() + } +} + +func (data *RouterHSRPInterfaceAddressFamilyIPv6V2Data) fromBody(ctx context.Context, res []byte) { + if value := gjson.GetBytes(res, "name"); value.Exists() { + data.Name = types.StringValue(value.String()) + } + if value := gjson.GetBytes(res, "mac-address"); value.Exists() { + data.MacAddress = types.StringValue(value.String()) + } + if value := gjson.GetBytes(res, "timers.hold-time"); value.Exists() { + data.TimersHoldTime = types.Int64Value(value.Int()) + } + if value := gjson.GetBytes(res, "timers.hold-time2"); value.Exists() { + data.TimersHoldTime2 = types.Int64Value(value.Int()) + } + if value := gjson.GetBytes(res, "timers.msec"); value.Exists() { + data.TimersMsec = types.Int64Value(value.Int()) + } + if value := gjson.GetBytes(res, "timers.msec2"); value.Exists() { + data.TimersMsec2 = types.Int64Value(value.Int()) + } + if value := gjson.GetBytes(res, "preempt.delay"); value.Exists() { + data.PreemptDelay = types.Int64Value(value.Int()) + } + if value := gjson.GetBytes(res, "priority"); value.Exists() { + data.Priority = types.Int64Value(value.Int()) + } + if value := gjson.GetBytes(res, "bfd.fast-detect.peer.ipv6"); value.Exists() { + data.BfdFastDetectPeerIpv6 = types.StringValue(value.String()) + } + if value := gjson.GetBytes(res, "bfd.fast-detect.peer.interface"); value.Exists() { + data.BfdFastDetectPeerInterface = types.StringValue(value.String()) + } + if value := gjson.GetBytes(res, "track-objects.track-object"); value.Exists() { + data.TrackObjects = make([]RouterHSRPInterfaceAddressFamilyIPv6V2TrackObjects, 0) + value.ForEach(func(k, v gjson.Result) bool { + item := RouterHSRPInterfaceAddressFamilyIPv6V2TrackObjects{} + if cValue := v.Get("object-name"); cValue.Exists() { + item.ObjectName = types.StringValue(cValue.String()) + } + if cValue := v.Get("priority-decrement"); cValue.Exists() { + item.PriorityDecrement = types.Int64Value(cValue.Int()) + } + data.TrackObjects = append(data.TrackObjects, item) + return true + }) + } + if value := gjson.GetBytes(res, "track-interfaces.track-interface"); value.Exists() { + data.TrackInterfaces = make([]RouterHSRPInterfaceAddressFamilyIPv6V2TrackInterfaces, 0) + value.ForEach(func(k, v gjson.Result) bool { + item := RouterHSRPInterfaceAddressFamilyIPv6V2TrackInterfaces{} + if cValue := v.Get("track-name"); cValue.Exists() { + item.TrackName = types.StringValue(cValue.String()) + } + if cValue := v.Get("priority-decrement"); cValue.Exists() { + item.PriorityDecrement = types.Int64Value(cValue.Int()) + } + data.TrackInterfaces = append(data.TrackInterfaces, item) + return true + }) + } + if value := gjson.GetBytes(res, "address.globals.global"); value.Exists() { + data.AddressGlobals = make([]RouterHSRPInterfaceAddressFamilyIPv6V2AddressGlobals, 0) + value.ForEach(func(k, v gjson.Result) bool { + item := RouterHSRPInterfaceAddressFamilyIPv6V2AddressGlobals{} + if cValue := v.Get("address"); cValue.Exists() { + item.Address = types.StringValue(cValue.String()) + } + data.AddressGlobals = append(data.AddressGlobals, item) + return true + }) + } + if value := gjson.GetBytes(res, "address.link-local.autoconfig.legacy-compatible"); value.Exists() { + data.AddressLinkLocalAutoconfigLegacyCompatible = types.BoolValue(true) + } else { + data.AddressLinkLocalAutoconfigLegacyCompatible = types.BoolValue(false) + } + if value := gjson.GetBytes(res, "address.link-local.ipv6-address"); value.Exists() { + data.AddressLinkLocalIpv6Address = types.StringValue(value.String()) + } +} + +func (data *RouterHSRPInterfaceAddressFamilyIPv6V2) getDeletedListItems(ctx context.Context, state RouterHSRPInterfaceAddressFamilyIPv6V2) []string { + deletedListItems := make([]string, 0) + for i := range state.TrackObjects { + keys := [...]string{"object-name"} + stateKeyValues := [...]string{state.TrackObjects[i].ObjectName.ValueString()} + + emptyKeys := true + if !reflect.ValueOf(state.TrackObjects[i].ObjectName.ValueString()).IsZero() { + emptyKeys = false + } + if emptyKeys { + continue + } + + found := false + for j := range data.TrackObjects { + found = true + if state.TrackObjects[i].ObjectName.ValueString() != data.TrackObjects[j].ObjectName.ValueString() { + found = false + } + if found { + break + } + } + if !found { + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + stateKeyValues[ki] + "]" + } + deletedListItems = append(deletedListItems, fmt.Sprintf("%v/track-objects/track-object%v", state.getPath(), keyString)) + } + } + for i := range state.TrackInterfaces { + keys := [...]string{"track-name"} + stateKeyValues := [...]string{state.TrackInterfaces[i].TrackName.ValueString()} + + emptyKeys := true + if !reflect.ValueOf(state.TrackInterfaces[i].TrackName.ValueString()).IsZero() { + emptyKeys = false + } + if emptyKeys { + continue + } + + found := false + for j := range data.TrackInterfaces { + found = true + if state.TrackInterfaces[i].TrackName.ValueString() != data.TrackInterfaces[j].TrackName.ValueString() { + found = false + } + if found { + break + } + } + if !found { + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + stateKeyValues[ki] + "]" + } + deletedListItems = append(deletedListItems, fmt.Sprintf("%v/track-interfaces/track-interface%v", state.getPath(), keyString)) + } + } + for i := range state.AddressGlobals { + keys := [...]string{"address"} + stateKeyValues := [...]string{state.AddressGlobals[i].Address.ValueString()} + + emptyKeys := true + if !reflect.ValueOf(state.AddressGlobals[i].Address.ValueString()).IsZero() { + emptyKeys = false + } + if emptyKeys { + continue + } + + found := false + for j := range data.AddressGlobals { + found = true + if state.AddressGlobals[i].Address.ValueString() != data.AddressGlobals[j].Address.ValueString() { + found = false + } + if found { + break + } + } + if !found { + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + stateKeyValues[ki] + "]" + } + deletedListItems = append(deletedListItems, fmt.Sprintf("%v/address/globals/global%v", state.getPath(), keyString)) + } + } + return deletedListItems +} + +func (data *RouterHSRPInterfaceAddressFamilyIPv6V2) getEmptyLeafsDelete(ctx context.Context) []string { + emptyLeafsDelete := make([]string, 0) + for i := range data.TrackObjects { + keys := [...]string{"object-name"} + keyValues := [...]string{data.TrackObjects[i].ObjectName.ValueString()} + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]" + } + } + for i := range data.TrackInterfaces { + keys := [...]string{"track-name"} + keyValues := [...]string{data.TrackInterfaces[i].TrackName.ValueString()} + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]" + } + } + for i := range data.AddressGlobals { + keys := [...]string{"address"} + keyValues := [...]string{data.AddressGlobals[i].Address.ValueString()} + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]" + } + } + if !data.AddressLinkLocalAutoconfigLegacyCompatible.IsNull() && !data.AddressLinkLocalAutoconfigLegacyCompatible.ValueBool() { + emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/address/link-local/autoconfig/legacy-compatible", data.getPath())) + } + return emptyLeafsDelete +} + +func (data *RouterHSRPInterfaceAddressFamilyIPv6V2) getDeletePaths(ctx context.Context) []string { + var deletePaths []string + if !data.Name.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/name", data.getPath())) + } + if !data.MacAddress.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/mac-address", data.getPath())) + } + if !data.TimersHoldTime.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/timers/hold-time", data.getPath())) + } + if !data.TimersHoldTime2.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/timers/hold-time2", data.getPath())) + } + if !data.TimersMsec.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/timers/msec", data.getPath())) + } + if !data.TimersMsec2.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/timers/msec2", data.getPath())) + } + if !data.PreemptDelay.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/preempt/delay", data.getPath())) + } + if !data.Priority.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/priority", data.getPath())) + } + if !data.BfdFastDetectPeerIpv6.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/bfd/fast-detect/peer/ipv6", data.getPath())) + } + if !data.BfdFastDetectPeerInterface.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/bfd/fast-detect/peer/interface", data.getPath())) + } + for i := range data.TrackObjects { + keys := [...]string{"object-name"} + keyValues := [...]string{data.TrackObjects[i].ObjectName.ValueString()} + + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]" + } + deletePaths = append(deletePaths, fmt.Sprintf("%v/track-objects/track-object%v", data.getPath(), keyString)) + } + for i := range data.TrackInterfaces { + keys := [...]string{"track-name"} + keyValues := [...]string{data.TrackInterfaces[i].TrackName.ValueString()} + + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]" + } + deletePaths = append(deletePaths, fmt.Sprintf("%v/track-interfaces/track-interface%v", data.getPath(), keyString)) + } + for i := range data.AddressGlobals { + keys := [...]string{"address"} + keyValues := [...]string{data.AddressGlobals[i].Address.ValueString()} + + keyString := "" + for ki := range keys { + keyString += "[" + keys[ki] + "=" + keyValues[ki] + "]" + } + deletePaths = append(deletePaths, fmt.Sprintf("%v/address/globals/global%v", data.getPath(), keyString)) + } + if !data.AddressLinkLocalAutoconfigLegacyCompatible.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/address/link-local/autoconfig/legacy-compatible", data.getPath())) + } + if !data.AddressLinkLocalIpv6Address.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/address/link-local/ipv6-address", data.getPath())) + } + return deletePaths +} diff --git a/internal/provider/resource_iosxr_router_hsrp_interface_address_family_ipv6_v1.go b/internal/provider/resource_iosxr_router_hsrp_interface_address_family_ipv6_v1.go new file mode 100644 index 00000000..f0ce0713 --- /dev/null +++ b/internal/provider/resource_iosxr_router_hsrp_interface_address_family_ipv6_v1.go @@ -0,0 +1,417 @@ +// 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/int64planmodifier" + "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 NewRouterHSRPInterfaceAddressFamilyIPv6V1Resource() resource.Resource { + return &RouterHSRPInterfaceAddressFamilyIPv6V1Resource{} +} + +type RouterHSRPInterfaceAddressFamilyIPv6V1Resource struct { + client *client.Client +} + +func (r *RouterHSRPInterfaceAddressFamilyIPv6V1Resource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_router_hsrp_interface_address_family_ipv6_v1" +} + +func (r *RouterHSRPInterfaceAddressFamilyIPv6V1Resource) 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 Router HSRP Interface Address Family IPv6 V1 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"), + }, + }, + "interface_name": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("HSRP interface configuration subcommands").String, + Required: true, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexp.MustCompile(`[a-zA-Z0-9.:_/-]+`), ""), + }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "group_number_version_1_id": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("group number version 1").AddIntegerRangeDescription(0, 255).String, + Required: true, + Validators: []validator.Int64{ + int64validator.Between(0, 255), + }, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + }, + "name": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("MGO session name").String, + Optional: true, + Validators: []validator.String{ + stringvalidator.LengthBetween(1, 800), + stringvalidator.RegexMatches(regexp.MustCompile(`[\w\-\.:,_@#%$\+=\|;]+`), ""), + }, + }, + "mac_address": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Use specified mac address for the virtual router").String, + Optional: true, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexp.MustCompile(`[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}`), ""), + }, + }, + "timers_hold_time": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Hold time in seconds").AddIntegerRangeDescription(1, 255).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(1, 255), + }, + }, + "timers_hold_time2": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Hold time in seconds").AddIntegerRangeDescription(1, 255).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(1, 255), + }, + }, + "timers_msec": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Specify hellotime in milliseconds").AddIntegerRangeDescription(100, 3000).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(100, 3000), + }, + }, + "timers_msec2": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Specify hold time in milliseconds").AddIntegerRangeDescription(100, 3000).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(100, 3000), + }, + }, + "preempt_delay": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Wait before preempting").AddIntegerRangeDescription(0, 3600).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(0, 3600), + }, + }, + "priority": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Priority level").AddIntegerRangeDescription(0, 255).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(0, 255), + }, + }, + "bfd_fast_detect_peer_ipv6": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("BFD peer interface 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:\.]*`), ""), + }, + }, + "bfd_fast_detect_peer_interface": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Select an interface over which to run BFD").String, + Optional: true, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexp.MustCompile(`[a-zA-Z0-9.:_/-]+`), ""), + }, + }, + "track_objects": schema.ListNestedAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Object tracking").String, + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "object_name": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Object tracking").String, + Required: true, + Validators: []validator.String{ + stringvalidator.LengthBetween(1, 800), + stringvalidator.RegexMatches(regexp.MustCompile(`[\w\-\.:,_@#%$\+=\|;]+`), ""), + }, + }, + "priority_decrement": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Priority decrement").AddIntegerRangeDescription(1, 255).String, + Required: true, + Validators: []validator.Int64{ + int64validator.Between(1, 255), + }, + }, + }, + }, + }, + "track_interfaces": schema.ListNestedAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Configure tracking").String, + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "track_name": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Configure tracking").String, + Required: true, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexp.MustCompile(`[a-zA-Z0-9.:_/-]+`), ""), + }, + }, + "priority_decrement": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Priority decrement").AddIntegerRangeDescription(1, 255).String, + Required: true, + Validators: []validator.Int64{ + int64validator.Between(1, 255), + }, + }, + }, + }, + }, + "address_globals": schema.ListNestedAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Global HSRP IPv6 address").String, + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "address": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Set Global HSRP IPv6 address").String, + Required: 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:\.]*`), ""), + }, + }, + }, + }, + }, + "address_link_local_autoconfig_legacy_compatible": schema.BoolAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Autoconfigure for Legacy compatibility (with IOS/NX-OS)").String, + Optional: true, + }, + "address_link_local_ipv6_address": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("HSRP IPv6 linklocal 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:\.]*`), ""), + }, + }, + }, + } +} + +func (r *RouterHSRPInterfaceAddressFamilyIPv6V1Resource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + r.client = req.ProviderData.(*client.Client) +} + +func (r *RouterHSRPInterfaceAddressFamilyIPv6V1Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var plan RouterHSRPInterfaceAddressFamilyIPv6V1 + + // 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 *RouterHSRPInterfaceAddressFamilyIPv6V1Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var state RouterHSRPInterfaceAddressFamilyIPv6V1 + + // 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 *RouterHSRPInterfaceAddressFamilyIPv6V1Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var plan, state RouterHSRPInterfaceAddressFamilyIPv6V1 + + // 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 *RouterHSRPInterfaceAddressFamilyIPv6V1Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var state RouterHSRPInterfaceAddressFamilyIPv6V1 + + // 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 *RouterHSRPInterfaceAddressFamilyIPv6V1Resource) 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_router_hsrp_interface_address_family_ipv6_v1_test.go b/internal/provider/resource_iosxr_router_hsrp_interface_address_family_ipv6_v1_test.go new file mode 100644 index 00000000..df709290 --- /dev/null +++ b/internal/provider/resource_iosxr_router_hsrp_interface_address_family_ipv6_v1_test.go @@ -0,0 +1,102 @@ +// 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 TestAccIosxrRouterHSRPInterfaceAddressFamilyIPv6V1(t *testing.T) { + var checks []resource.TestCheckFunc + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "group_number_version_1_id", "135")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "name", "gp1")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "mac_address", "00:02:00:01:00:01")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "timers_hold_time", "10")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "timers_hold_time2", "20")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "timers_msec", "100")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "timers_msec2", "130")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "preempt_delay", "256")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "priority", "244")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "bfd_fast_detect_peer_ipv6", "fe80::240:d0ff:fe48:4672")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "bfd_fast_detect_peer_interface", "GigabitEthernet0/0/0/2")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "track_objects.0.object_name", "TOBJ1")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "track_objects.0.priority_decrement", "10")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "track_interfaces.0.track_name", "GigabitEthernet0/0/0/4")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "track_interfaces.0.priority_decrement", "244")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v1.test", "address_link_local_autoconfig_legacy_compatible", "true")) + var steps []resource.TestStep + if os.Getenv("SKIP_MINIMUM_TEST") == "" { + steps = append(steps, resource.TestStep{ + Config: testAccIosxrRouterHSRPInterfaceAddressFamilyIPv6V1Config_minimum(), + }) + } + steps = append(steps, resource.TestStep{ + Config: testAccIosxrRouterHSRPInterfaceAddressFamilyIPv6V1Config_all(), + Check: resource.ComposeTestCheckFunc(checks...), + }) + steps = append(steps, resource.TestStep{ + ResourceName: "iosxr_router_hsrp_interface_address_family_ipv6_v1.test", + ImportState: true, + ImportStateId: "Cisco-IOS-XR-um-router-hsrp-cfg:/router/hsrp/interfaces/interface[interface-name=GigabitEthernet0/0/0/1]/address-family/ipv6/hsrp/group-number-version-1s/group-number-version-1[group-number-version-1-id=135]", + }) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: steps, + }) +} + +func testAccIosxrRouterHSRPInterfaceAddressFamilyIPv6V1Config_minimum() string { + config := `resource "iosxr_router_hsrp_interface_address_family_ipv6_v1" "test" {` + "\n" + config += ` interface_name = "GigabitEthernet0/0/0/1"` + "\n" + config += ` group_number_version_1_id = 135` + "\n" + config += `}` + "\n" + return config +} + +func testAccIosxrRouterHSRPInterfaceAddressFamilyIPv6V1Config_all() string { + config := `resource "iosxr_router_hsrp_interface_address_family_ipv6_v1" "test" {` + "\n" + config += ` interface_name = "GigabitEthernet0/0/0/1"` + "\n" + config += ` group_number_version_1_id = 135` + "\n" + config += ` name = "gp1"` + "\n" + config += ` mac_address = "00:02:00:01:00:01"` + "\n" + config += ` timers_hold_time = 10` + "\n" + config += ` timers_hold_time2 = 20` + "\n" + config += ` timers_msec = 100` + "\n" + config += ` timers_msec2 = 130` + "\n" + config += ` preempt_delay = 256` + "\n" + config += ` priority = 244` + "\n" + config += ` bfd_fast_detect_peer_ipv6 = "fe80::240:d0ff:fe48:4672"` + "\n" + config += ` bfd_fast_detect_peer_interface = "GigabitEthernet0/0/0/2"` + "\n" + config += ` track_objects = [{` + "\n" + config += ` object_name = "TOBJ1"` + "\n" + config += ` priority_decrement = 10` + "\n" + config += ` }]` + "\n" + config += ` track_interfaces = [{` + "\n" + config += ` track_name = "GigabitEthernet0/0/0/4"` + "\n" + config += ` priority_decrement = 244` + "\n" + config += ` }]` + "\n" + config += ` address_link_local_autoconfig_legacy_compatible = true` + "\n" + config += `}` + "\n" + return config +} diff --git a/internal/provider/resource_iosxr_router_hsrp_interface_address_family_ipv6_v2.go b/internal/provider/resource_iosxr_router_hsrp_interface_address_family_ipv6_v2.go new file mode 100644 index 00000000..fb25a72b --- /dev/null +++ b/internal/provider/resource_iosxr_router_hsrp_interface_address_family_ipv6_v2.go @@ -0,0 +1,417 @@ +// 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/int64planmodifier" + "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 NewRouterHSRPInterfaceAddressFamilyIPv6V2Resource() resource.Resource { + return &RouterHSRPInterfaceAddressFamilyIPv6V2Resource{} +} + +type RouterHSRPInterfaceAddressFamilyIPv6V2Resource struct { + client *client.Client +} + +func (r *RouterHSRPInterfaceAddressFamilyIPv6V2Resource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_router_hsrp_interface_address_family_ipv6_v2" +} + +func (r *RouterHSRPInterfaceAddressFamilyIPv6V2Resource) 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 Router HSRP Interface Address Family IPv6 V2 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"), + }, + }, + "interface_name": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("HSRP interface configuration subcommands").String, + Required: true, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexp.MustCompile(`[a-zA-Z0-9.:_/-]+`), ""), + }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "group_number_version_2_id": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("group number version 2").AddIntegerRangeDescription(0, 4095).String, + Required: true, + Validators: []validator.Int64{ + int64validator.Between(0, 4095), + }, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + }, + "name": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("MGO session name").String, + Optional: true, + Validators: []validator.String{ + stringvalidator.LengthBetween(1, 800), + stringvalidator.RegexMatches(regexp.MustCompile(`[\w\-\.:,_@#%$\+=\|;]+`), ""), + }, + }, + "mac_address": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Use specified mac address for the virtual router").String, + Optional: true, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexp.MustCompile(`[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}`), ""), + }, + }, + "timers_hold_time": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Hold time in seconds").AddIntegerRangeDescription(1, 255).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(1, 255), + }, + }, + "timers_hold_time2": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Hold time in seconds").AddIntegerRangeDescription(1, 255).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(1, 255), + }, + }, + "timers_msec": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Specify hellotime in milliseconds").AddIntegerRangeDescription(100, 3000).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(100, 3000), + }, + }, + "timers_msec2": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Specify hold time in milliseconds").AddIntegerRangeDescription(100, 3000).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(100, 3000), + }, + }, + "preempt_delay": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Wait before preempting").AddIntegerRangeDescription(0, 3600).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(0, 3600), + }, + }, + "priority": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Priority level").AddIntegerRangeDescription(0, 255).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(0, 255), + }, + }, + "bfd_fast_detect_peer_ipv6": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("BFD peer interface 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:\.]*`), ""), + }, + }, + "bfd_fast_detect_peer_interface": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Select an interface over which to run BFD").String, + Optional: true, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexp.MustCompile(`[a-zA-Z0-9.:_/-]+`), ""), + }, + }, + "track_objects": schema.ListNestedAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Object tracking").String, + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "object_name": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Object tracking").String, + Required: true, + Validators: []validator.String{ + stringvalidator.LengthBetween(1, 800), + stringvalidator.RegexMatches(regexp.MustCompile(`[\w\-\.:,_@#%$\+=\|;]+`), ""), + }, + }, + "priority_decrement": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Priority decrement").AddIntegerRangeDescription(1, 255).String, + Required: true, + Validators: []validator.Int64{ + int64validator.Between(1, 255), + }, + }, + }, + }, + }, + "track_interfaces": schema.ListNestedAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Configure tracking").String, + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "track_name": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Configure tracking").String, + Required: true, + Validators: []validator.String{ + stringvalidator.RegexMatches(regexp.MustCompile(`[a-zA-Z0-9.:_/-]+`), ""), + }, + }, + "priority_decrement": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Priority decrement").AddIntegerRangeDescription(1, 255).String, + Required: true, + Validators: []validator.Int64{ + int64validator.Between(1, 255), + }, + }, + }, + }, + }, + "address_globals": schema.ListNestedAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Global HSRP IPv6 address").String, + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "address": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Set Global HSRP IPv6 address").String, + Required: 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:\.]*`), ""), + }, + }, + }, + }, + }, + "address_link_local_autoconfig_legacy_compatible": schema.BoolAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Autoconfigure for Legacy compatibility (with IOS/NX-OS)").String, + Optional: true, + }, + "address_link_local_ipv6_address": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("HSRP IPv6 linklocal 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:\.]*`), ""), + }, + }, + }, + } +} + +func (r *RouterHSRPInterfaceAddressFamilyIPv6V2Resource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + r.client = req.ProviderData.(*client.Client) +} + +func (r *RouterHSRPInterfaceAddressFamilyIPv6V2Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var plan RouterHSRPInterfaceAddressFamilyIPv6V2 + + // 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 *RouterHSRPInterfaceAddressFamilyIPv6V2Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var state RouterHSRPInterfaceAddressFamilyIPv6V2 + + // 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 *RouterHSRPInterfaceAddressFamilyIPv6V2Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var plan, state RouterHSRPInterfaceAddressFamilyIPv6V2 + + // 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 *RouterHSRPInterfaceAddressFamilyIPv6V2Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var state RouterHSRPInterfaceAddressFamilyIPv6V2 + + // 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 *RouterHSRPInterfaceAddressFamilyIPv6V2Resource) 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_router_hsrp_interface_address_family_ipv6_v2_test.go b/internal/provider/resource_iosxr_router_hsrp_interface_address_family_ipv6_v2_test.go new file mode 100644 index 00000000..761ab812 --- /dev/null +++ b/internal/provider/resource_iosxr_router_hsrp_interface_address_family_ipv6_v2_test.go @@ -0,0 +1,106 @@ +// 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 TestAccIosxrRouterHSRPInterfaceAddressFamilyIPv6V2(t *testing.T) { + var checks []resource.TestCheckFunc + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "group_number_version_2_id", "4055")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "name", "gp2")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "mac_address", "00:01:00:02:00:02")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "timers_hold_time", "10")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "timers_hold_time2", "20")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "timers_msec", "100")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "timers_msec2", "130")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "preempt_delay", "256")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "priority", "244")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "bfd_fast_detect_peer_ipv6", "fe80::240:d0ff:fe48:4672")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "bfd_fast_detect_peer_interface", "GigabitEthernet0/0/0/3")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "track_objects.0.object_name", "TOBJ2")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "track_objects.0.priority_decrement", "10")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "track_interfaces.0.track_name", "GigabitEthernet0/0/0/4")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "track_interfaces.0.priority_decrement", "244")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "address_globals.0.address", "2001:db8:cafe:2100::bad1:1010")) + checks = append(checks, resource.TestCheckResourceAttr("iosxr_router_hsrp_interface_address_family_ipv6_v2.test", "address_link_local_autoconfig_legacy_compatible", "true")) + var steps []resource.TestStep + if os.Getenv("SKIP_MINIMUM_TEST") == "" { + steps = append(steps, resource.TestStep{ + Config: testAccIosxrRouterHSRPInterfaceAddressFamilyIPv6V2Config_minimum(), + }) + } + steps = append(steps, resource.TestStep{ + Config: testAccIosxrRouterHSRPInterfaceAddressFamilyIPv6V2Config_all(), + Check: resource.ComposeTestCheckFunc(checks...), + }) + steps = append(steps, resource.TestStep{ + ResourceName: "iosxr_router_hsrp_interface_address_family_ipv6_v2.test", + ImportState: true, + ImportStateId: "Cisco-IOS-XR-um-router-hsrp-cfg:/router/hsrp/interfaces/interface[interface-name=GigabitEthernet0/0/0/2]/address-family/ipv6/hsrp/group-number-version-2s/group-number-version-2[group-number-version-2-id=4055]", + }) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: steps, + }) +} + +func testAccIosxrRouterHSRPInterfaceAddressFamilyIPv6V2Config_minimum() string { + config := `resource "iosxr_router_hsrp_interface_address_family_ipv6_v2" "test" {` + "\n" + config += ` interface_name = "GigabitEthernet0/0/0/2"` + "\n" + config += ` group_number_version_2_id = 4055` + "\n" + config += `}` + "\n" + return config +} + +func testAccIosxrRouterHSRPInterfaceAddressFamilyIPv6V2Config_all() string { + config := `resource "iosxr_router_hsrp_interface_address_family_ipv6_v2" "test" {` + "\n" + config += ` interface_name = "GigabitEthernet0/0/0/2"` + "\n" + config += ` group_number_version_2_id = 4055` + "\n" + config += ` name = "gp2"` + "\n" + config += ` mac_address = "00:01:00:02:00:02"` + "\n" + config += ` timers_hold_time = 10` + "\n" + config += ` timers_hold_time2 = 20` + "\n" + config += ` timers_msec = 100` + "\n" + config += ` timers_msec2 = 130` + "\n" + config += ` preempt_delay = 256` + "\n" + config += ` priority = 244` + "\n" + config += ` bfd_fast_detect_peer_ipv6 = "fe80::240:d0ff:fe48:4672"` + "\n" + config += ` bfd_fast_detect_peer_interface = "GigabitEthernet0/0/0/3"` + "\n" + config += ` track_objects = [{` + "\n" + config += ` object_name = "TOBJ2"` + "\n" + config += ` priority_decrement = 10` + "\n" + config += ` }]` + "\n" + config += ` track_interfaces = [{` + "\n" + config += ` track_name = "GigabitEthernet0/0/0/4"` + "\n" + config += ` priority_decrement = 244` + "\n" + config += ` }]` + "\n" + config += ` address_globals = [{` + "\n" + config += ` address = "2001:db8:cafe:2100::bad1:1010"` + "\n" + config += ` }]` + "\n" + config += ` address_link_local_autoconfig_legacy_compatible = true` + "\n" + config += `}` + "\n" + return config +}