diff --git a/CHANGELOG.md b/CHANGELOG.md index 552386456..fe30a6776 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Add `iosxe_bgp_template_peer_policy` resource - Add `ip_dhcp_relay_information_option_vpn_id` attribute to `iosxe_interface_ethernet` resource and `iosxe_interface_vlan` resource - Add `local_routing` attribute to `iosxe_interface_nve` resource and data source +- Add `ipv4_unicast_maximum_paths_ebgp` and `ipv4_unicast_maximum_paths_ibgp` attributes to the `iosxe_bgp_address_family_ipv4` and `iosxe_bgp_address_family_ipv4_vrf` resources ## 0.9.3 diff --git a/docs/data-sources/bgp_address_family_ipv4.md b/docs/data-sources/bgp_address_family_ipv4.md index ba7b4ac1d..f2565fcaf 100644 --- a/docs/data-sources/bgp_address_family_ipv4.md +++ b/docs/data-sources/bgp_address_family_ipv4.md @@ -39,6 +39,8 @@ data "iosxe_bgp_address_family_ipv4" "example" { - `ipv4_unicast_distance_bgp_external` (Number) - `ipv4_unicast_distance_bgp_internal` (Number) - `ipv4_unicast_distance_bgp_local` (Number) +- `ipv4_unicast_maximum_paths_ebgp` (Number) eBGP-multipath +- `ipv4_unicast_maximum_paths_ibgp` (Number) iBGP-multipath - `ipv4_unicast_networks` (Attributes List) Specify a network to announce via BGP (see [below for nested schema](#nestedatt--ipv4_unicast_networks)) - `ipv4_unicast_networks_mask` (Attributes List) Specify a network to announce via BGP (see [below for nested schema](#nestedatt--ipv4_unicast_networks_mask)) - `ipv4_unicast_redistribute_connected` (Boolean) Connected diff --git a/docs/data-sources/bgp_address_family_ipv4_vrf.md b/docs/data-sources/bgp_address_family_ipv4_vrf.md index d0664c20a..165f04a6e 100644 --- a/docs/data-sources/bgp_address_family_ipv4_vrf.md +++ b/docs/data-sources/bgp_address_family_ipv4_vrf.md @@ -47,6 +47,8 @@ Read-Only: - `ipv4_unicast_distance_bgp_external` (Number) - `ipv4_unicast_distance_bgp_internal` (Number) - `ipv4_unicast_distance_bgp_local` (Number) +- `ipv4_unicast_maximum_paths_ebgp` (Number) eBGP-multipath +- `ipv4_unicast_maximum_paths_ibgp` (Number) - `ipv4_unicast_networks` (Attributes List) Specify a network to announce via BGP (see [below for nested schema](#nestedatt--vrfs--ipv4_unicast_networks)) - `ipv4_unicast_networks_mask` (Attributes List) Specify a network to announce via BGP (see [below for nested schema](#nestedatt--vrfs--ipv4_unicast_networks_mask)) - `ipv4_unicast_redistribute_connected` (Boolean) Connected diff --git a/docs/guides/changelog.md b/docs/guides/changelog.md index 2870dad41..f957cb5a8 100644 --- a/docs/guides/changelog.md +++ b/docs/guides/changelog.md @@ -19,6 +19,7 @@ description: |- - Add `iosxe_bgp_template_peer_policy` resource - Add `ip_dhcp_relay_information_option_vpn_id` attribute to `iosxe_interface_ethernet` resource and `iosxe_interface_vlan` resource - Add `local_routing` attribute to `iosxe_interface_nve` resource and data source +- Add `ipv4_unicast_maximum_paths_ebgp` and `ipv4_unicast_maximum_paths_ibgp` attributes to the `iosxe_bgp_address_family_ipv4` and `iosxe_bgp_address_family_ipv4_vrf` resources ## 0.9.3 diff --git a/docs/resources/bgp_address_family_ipv4.md b/docs/resources/bgp_address_family_ipv4.md index c5c55d5de..a40d67719 100644 --- a/docs/resources/bgp_address_family_ipv4.md +++ b/docs/resources/bgp_address_family_ipv4.md @@ -49,6 +49,8 @@ resource "iosxe_bgp_address_family_ipv4" "example" { ipv4_unicast_distance_bgp_external = 20 ipv4_unicast_distance_bgp_internal = 200 ipv4_unicast_distance_bgp_local = 200 + ipv4_unicast_maximum_paths_ebgp = 2 + ipv4_unicast_maximum_paths_ibgp = 2 } ``` @@ -70,6 +72,10 @@ resource "iosxe_bgp_address_family_ipv4" "example" { - `ipv4_unicast_distance_bgp_external` (Number) - Range: `1`-`255` - `ipv4_unicast_distance_bgp_internal` (Number) - Range: `1`-`255` - `ipv4_unicast_distance_bgp_local` (Number) - Range: `1`-`255` +- `ipv4_unicast_maximum_paths_ebgp` (Number) eBGP-multipath + - Range: `1`-`32` +- `ipv4_unicast_maximum_paths_ibgp` (Number) iBGP-multipath + - Range: `1`-`32` - `ipv4_unicast_networks` (Attributes List) Specify a network to announce via BGP (see [below for nested schema](#nestedatt--ipv4_unicast_networks)) - `ipv4_unicast_networks_mask` (Attributes List) Specify a network to announce via BGP (see [below for nested schema](#nestedatt--ipv4_unicast_networks_mask)) - `ipv4_unicast_redistribute_connected` (Boolean) Connected diff --git a/docs/resources/bgp_address_family_ipv4_vrf.md b/docs/resources/bgp_address_family_ipv4_vrf.md index ea27ddac1..87779f453 100644 --- a/docs/resources/bgp_address_family_ipv4_vrf.md +++ b/docs/resources/bgp_address_family_ipv4_vrf.md @@ -54,6 +54,8 @@ resource "iosxe_bgp_address_family_ipv4_vrf" "example" { ipv4_unicast_distance_bgp_external = 20 ipv4_unicast_distance_bgp_internal = 200 ipv4_unicast_distance_bgp_local = 200 + ipv4_unicast_maximum_paths_ebgp = 2 + ipv4_unicast_maximum_paths_ibgp = 2 } ] } @@ -93,6 +95,9 @@ Optional: - `ipv4_unicast_distance_bgp_external` (Number) - Range: `1`-`255` - `ipv4_unicast_distance_bgp_internal` (Number) - Range: `1`-`255` - `ipv4_unicast_distance_bgp_local` (Number) - Range: `1`-`255` +- `ipv4_unicast_maximum_paths_ebgp` (Number) eBGP-multipath + - Range: `1`-`32` +- `ipv4_unicast_maximum_paths_ibgp` (Number) - Range: `1`-`32` - `ipv4_unicast_networks` (Attributes List) Specify a network to announce via BGP (see [below for nested schema](#nestedatt--vrfs--ipv4_unicast_networks)) - `ipv4_unicast_networks_mask` (Attributes List) Specify a network to announce via BGP (see [below for nested schema](#nestedatt--vrfs--ipv4_unicast_networks_mask)) - `ipv4_unicast_redistribute_connected` (Boolean) Connected diff --git a/examples/resources/iosxe_bgp_address_family_ipv4/resource.tf b/examples/resources/iosxe_bgp_address_family_ipv4/resource.tf index f6f64f7fd..5df6999dc 100644 --- a/examples/resources/iosxe_bgp_address_family_ipv4/resource.tf +++ b/examples/resources/iosxe_bgp_address_family_ipv4/resource.tf @@ -34,4 +34,6 @@ resource "iosxe_bgp_address_family_ipv4" "example" { ipv4_unicast_distance_bgp_external = 20 ipv4_unicast_distance_bgp_internal = 200 ipv4_unicast_distance_bgp_local = 200 + ipv4_unicast_maximum_paths_ebgp = 2 + ipv4_unicast_maximum_paths_ibgp = 2 } diff --git a/examples/resources/iosxe_bgp_address_family_ipv4_vrf/resource.tf b/examples/resources/iosxe_bgp_address_family_ipv4_vrf/resource.tf index d693d4633..319560f2f 100644 --- a/examples/resources/iosxe_bgp_address_family_ipv4_vrf/resource.tf +++ b/examples/resources/iosxe_bgp_address_family_ipv4_vrf/resource.tf @@ -39,6 +39,8 @@ resource "iosxe_bgp_address_family_ipv4_vrf" "example" { ipv4_unicast_distance_bgp_external = 20 ipv4_unicast_distance_bgp_internal = 200 ipv4_unicast_distance_bgp_local = 200 + ipv4_unicast_maximum_paths_ebgp = 2 + ipv4_unicast_maximum_paths_ibgp = 2 } ] } diff --git a/gen/definitions/bgp_address_family_ipv4.yaml b/gen/definitions/bgp_address_family_ipv4.yaml index 051f6c230..b5431b57c 100644 --- a/gen/definitions/bgp_address_family_ipv4.yaml +++ b/gen/definitions/bgp_address_family_ipv4.yaml @@ -77,6 +77,12 @@ attributes: example: 200 - yang_name: ipv4-unicast/distance/bgp/local example: 200 + - yang_name: ipv4-unicast/maximum-paths/ebgp + tf_name: ipv4_unicast_maximum_paths_ebgp + example: 2 + - yang_name: ipv4-unicast/maximum-paths/ibgp-leaf + tf_name: ipv4_unicast_maximum_paths_ibgp + example: 2 test_prerequisites: - path: Cisco-IOS-XE-native:native/router/Cisco-IOS-XE-bgp:bgp=65000 diff --git a/gen/definitions/bgp_address_family_ipv4_vrf.yaml b/gen/definitions/bgp_address_family_ipv4_vrf.yaml index bb7b10c1e..35adb12e3 100644 --- a/gen/definitions/bgp_address_family_ipv4_vrf.yaml +++ b/gen/definitions/bgp_address_family_ipv4_vrf.yaml @@ -29,6 +29,7 @@ attributes: - yang_name: ipv4-unicast/bgp/router-id/id-choice/ip-id/ip-id xpath: ipv4-unicast/bgp/router-id/ip-id tf_name: ipv4_unicast_router_id_ip + exclude_test: true example: 10.1.1.1 exclude_test: true - yang_name: ipv4-unicast/aggregate-address @@ -111,7 +112,13 @@ attributes: example: 200 - yang_name: ipv4-unicast/distance/bgp/local example: 200 - + - yang_name: ipv4-unicast/maximum-paths/ebgp + tf_name: ipv4_unicast_maximum_paths_ebgp + example: 2 + - yang_name: ipv4-unicast/maximum-paths/ibgp/ibgp-choice/max/max + tf_name: ipv4_unicast_maximum_paths_ibgp + xpath: ipv4-unicast/maximum-paths/ibgp/max + example: 2 test_prerequisites: - path: Cisco-IOS-XE-native:native/vrf/definition=VRF1 no_delete: true diff --git a/internal/provider/data_source_iosxe_bgp_address_family_ipv4.go b/internal/provider/data_source_iosxe_bgp_address_family_ipv4.go index 275fc961d..e148fc09e 100644 --- a/internal/provider/data_source_iosxe_bgp_address_family_ipv4.go +++ b/internal/provider/data_source_iosxe_bgp_address_family_ipv4.go @@ -179,6 +179,14 @@ func (d *BGPAddressFamilyIPv4DataSource) Schema(ctx context.Context, req datasou MarkdownDescription: "", Computed: true, }, + "ipv4_unicast_maximum_paths_ebgp": schema.Int64Attribute{ + MarkdownDescription: "eBGP-multipath", + Computed: true, + }, + "ipv4_unicast_maximum_paths_ibgp": schema.Int64Attribute{ + MarkdownDescription: "iBGP-multipath", + Computed: true, + }, }, } } diff --git a/internal/provider/data_source_iosxe_bgp_address_family_ipv4_test.go b/internal/provider/data_source_iosxe_bgp_address_family_ipv4_test.go index 9cd23f028..fba33fed5 100644 --- a/internal/provider/data_source_iosxe_bgp_address_family_ipv4_test.go +++ b/internal/provider/data_source_iosxe_bgp_address_family_ipv4_test.go @@ -49,6 +49,8 @@ func TestAccDataSourceIosxeBGPAddressFamilyIPv4(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_bgp_address_family_ipv4.test", "ipv4_unicast_distance_bgp_external", "20")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_bgp_address_family_ipv4.test", "ipv4_unicast_distance_bgp_internal", "200")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_bgp_address_family_ipv4.test", "ipv4_unicast_distance_bgp_local", "200")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_bgp_address_family_ipv4.test", "ipv4_unicast_maximum_paths_ebgp", "2")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_bgp_address_family_ipv4.test", "ipv4_unicast_maximum_paths_ibgp", "2")) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, @@ -108,6 +110,8 @@ func testAccDataSourceIosxeBGPAddressFamilyIPv4Config() string { config += ` ipv4_unicast_distance_bgp_external = 20` + "\n" config += ` ipv4_unicast_distance_bgp_internal = 200` + "\n" config += ` ipv4_unicast_distance_bgp_local = 200` + "\n" + config += ` ipv4_unicast_maximum_paths_ebgp = 2` + "\n" + config += ` ipv4_unicast_maximum_paths_ibgp = 2` + "\n" config += ` depends_on = [iosxe_restconf.PreReq0, ]` + "\n" config += `}` + "\n" diff --git a/internal/provider/data_source_iosxe_bgp_address_family_ipv4_vrf.go b/internal/provider/data_source_iosxe_bgp_address_family_ipv4_vrf.go index b2e474882..e15103104 100644 --- a/internal/provider/data_source_iosxe_bgp_address_family_ipv4_vrf.go +++ b/internal/provider/data_source_iosxe_bgp_address_family_ipv4_vrf.go @@ -208,6 +208,14 @@ func (d *BGPAddressFamilyIPv4VRFDataSource) Schema(ctx context.Context, req data MarkdownDescription: "", Computed: true, }, + "ipv4_unicast_maximum_paths_ebgp": schema.Int64Attribute{ + MarkdownDescription: "eBGP-multipath", + Computed: true, + }, + "ipv4_unicast_maximum_paths_ibgp": schema.Int64Attribute{ + MarkdownDescription: "", + Computed: true, + }, }, }, }, diff --git a/internal/provider/data_source_iosxe_bgp_address_family_ipv4_vrf_test.go b/internal/provider/data_source_iosxe_bgp_address_family_ipv4_vrf_test.go index fe9fdef6a..3371b428f 100644 --- a/internal/provider/data_source_iosxe_bgp_address_family_ipv4_vrf_test.go +++ b/internal/provider/data_source_iosxe_bgp_address_family_ipv4_vrf_test.go @@ -52,6 +52,8 @@ func TestAccDataSourceIosxeBGPAddressFamilyIPv4VRF(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_bgp_address_family_ipv4_vrf.test", "vrfs.0.ipv4_unicast_distance_bgp_external", "20")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_bgp_address_family_ipv4_vrf.test", "vrfs.0.ipv4_unicast_distance_bgp_internal", "200")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_bgp_address_family_ipv4_vrf.test", "vrfs.0.ipv4_unicast_distance_bgp_local", "200")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_bgp_address_family_ipv4_vrf.test", "vrfs.0.ipv4_unicast_maximum_paths_ebgp", "2")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_bgp_address_family_ipv4_vrf.test", "vrfs.0.ipv4_unicast_maximum_paths_ibgp", "2")) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, @@ -137,6 +139,8 @@ func testAccDataSourceIosxeBGPAddressFamilyIPv4VRFConfig() string { config += ` ipv4_unicast_distance_bgp_external = 20` + "\n" config += ` ipv4_unicast_distance_bgp_internal = 200` + "\n" config += ` ipv4_unicast_distance_bgp_local = 200` + "\n" + config += ` ipv4_unicast_maximum_paths_ebgp = 2` + "\n" + config += ` ipv4_unicast_maximum_paths_ibgp = 2` + "\n" config += ` }]` + "\n" config += ` depends_on = [iosxe_restconf.PreReq0, iosxe_restconf.PreReq1, iosxe_restconf.PreReq2, ]` + "\n" config += `}` + "\n" diff --git a/internal/provider/model_iosxe_bgp_address_family_ipv4.go b/internal/provider/model_iosxe_bgp_address_family_ipv4.go index 2696107f2..1d95d63b9 100644 --- a/internal/provider/model_iosxe_bgp_address_family_ipv4.go +++ b/internal/provider/model_iosxe_bgp_address_family_ipv4.go @@ -53,6 +53,8 @@ type BGPAddressFamilyIPv4 struct { Ipv4UnicastDistanceBgpExternal types.Int64 `tfsdk:"ipv4_unicast_distance_bgp_external"` Ipv4UnicastDistanceBgpInternal types.Int64 `tfsdk:"ipv4_unicast_distance_bgp_internal"` Ipv4UnicastDistanceBgpLocal types.Int64 `tfsdk:"ipv4_unicast_distance_bgp_local"` + Ipv4UnicastMaximumPathsEbgp types.Int64 `tfsdk:"ipv4_unicast_maximum_paths_ebgp"` + Ipv4UnicastMaximumPathsIbgp types.Int64 `tfsdk:"ipv4_unicast_maximum_paths_ibgp"` } type BGPAddressFamilyIPv4Data struct { @@ -69,6 +71,8 @@ type BGPAddressFamilyIPv4Data struct { Ipv4UnicastDistanceBgpExternal types.Int64 `tfsdk:"ipv4_unicast_distance_bgp_external"` Ipv4UnicastDistanceBgpInternal types.Int64 `tfsdk:"ipv4_unicast_distance_bgp_internal"` Ipv4UnicastDistanceBgpLocal types.Int64 `tfsdk:"ipv4_unicast_distance_bgp_local"` + Ipv4UnicastMaximumPathsEbgp types.Int64 `tfsdk:"ipv4_unicast_maximum_paths_ebgp"` + Ipv4UnicastMaximumPathsIbgp types.Int64 `tfsdk:"ipv4_unicast_maximum_paths_ibgp"` } type BGPAddressFamilyIPv4Ipv4UnicastAggregateAddresses struct { Ipv4Address types.String `tfsdk:"ipv4_address"` @@ -143,6 +147,12 @@ func (data BGPAddressFamilyIPv4) toBody(ctx context.Context) string { if !data.Ipv4UnicastDistanceBgpLocal.IsNull() && !data.Ipv4UnicastDistanceBgpLocal.IsUnknown() { body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ipv4-unicast.distance.bgp.local", strconv.FormatInt(data.Ipv4UnicastDistanceBgpLocal.ValueInt64(), 10)) } + if !data.Ipv4UnicastMaximumPathsEbgp.IsNull() && !data.Ipv4UnicastMaximumPathsEbgp.IsUnknown() { + body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ipv4-unicast.maximum-paths.ebgp", strconv.FormatInt(data.Ipv4UnicastMaximumPathsEbgp.ValueInt64(), 10)) + } + if !data.Ipv4UnicastMaximumPathsIbgp.IsNull() && !data.Ipv4UnicastMaximumPathsIbgp.IsUnknown() { + body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ipv4-unicast.maximum-paths.ibgp-leaf", strconv.FormatInt(data.Ipv4UnicastMaximumPathsIbgp.ValueInt64(), 10)) + } if len(data.Ipv4UnicastAggregateAddresses) > 0 { body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ipv4-unicast.aggregate-address", []interface{}{}) for index, item := range data.Ipv4UnicastAggregateAddresses { @@ -425,6 +435,16 @@ func (data *BGPAddressFamilyIPv4) updateFromBody(ctx context.Context, res gjson. } else { data.Ipv4UnicastDistanceBgpLocal = types.Int64Null() } + if value := res.Get(prefix + "ipv4-unicast.maximum-paths.ebgp"); value.Exists() && !data.Ipv4UnicastMaximumPathsEbgp.IsNull() { + data.Ipv4UnicastMaximumPathsEbgp = types.Int64Value(value.Int()) + } else { + data.Ipv4UnicastMaximumPathsEbgp = types.Int64Null() + } + if value := res.Get(prefix + "ipv4-unicast.maximum-paths.ibgp-leaf"); value.Exists() && !data.Ipv4UnicastMaximumPathsIbgp.IsNull() { + data.Ipv4UnicastMaximumPathsIbgp = types.Int64Value(value.Int()) + } else { + data.Ipv4UnicastMaximumPathsIbgp = types.Int64Null() + } } // End of section. //template:end updateFromBody @@ -530,6 +550,12 @@ func (data *BGPAddressFamilyIPv4) fromBody(ctx context.Context, res gjson.Result if value := res.Get(prefix + "ipv4-unicast.distance.bgp.local"); value.Exists() { data.Ipv4UnicastDistanceBgpLocal = types.Int64Value(value.Int()) } + if value := res.Get(prefix + "ipv4-unicast.maximum-paths.ebgp"); value.Exists() { + data.Ipv4UnicastMaximumPathsEbgp = types.Int64Value(value.Int()) + } + if value := res.Get(prefix + "ipv4-unicast.maximum-paths.ibgp-leaf"); value.Exists() { + data.Ipv4UnicastMaximumPathsIbgp = types.Int64Value(value.Int()) + } } // End of section. //template:end fromBody @@ -635,6 +661,12 @@ func (data *BGPAddressFamilyIPv4Data) fromBody(ctx context.Context, res gjson.Re if value := res.Get(prefix + "ipv4-unicast.distance.bgp.local"); value.Exists() { data.Ipv4UnicastDistanceBgpLocal = types.Int64Value(value.Int()) } + if value := res.Get(prefix + "ipv4-unicast.maximum-paths.ebgp"); value.Exists() { + data.Ipv4UnicastMaximumPathsEbgp = types.Int64Value(value.Int()) + } + if value := res.Get(prefix + "ipv4-unicast.maximum-paths.ibgp-leaf"); value.Exists() { + data.Ipv4UnicastMaximumPathsIbgp = types.Int64Value(value.Int()) + } } // End of section. //template:end fromBodyData @@ -643,6 +675,12 @@ func (data *BGPAddressFamilyIPv4Data) fromBody(ctx context.Context, res gjson.Re func (data *BGPAddressFamilyIPv4) getDeletedItems(ctx context.Context, state BGPAddressFamilyIPv4) []string { deletedItems := make([]string, 0) + if !state.Ipv4UnicastMaximumPathsIbgp.IsNull() && data.Ipv4UnicastMaximumPathsIbgp.IsNull() { + deletedItems = append(deletedItems, fmt.Sprintf("%v/ipv4-unicast/maximum-paths/ibgp-leaf", state.getPath())) + } + if !state.Ipv4UnicastMaximumPathsEbgp.IsNull() && data.Ipv4UnicastMaximumPathsEbgp.IsNull() { + deletedItems = append(deletedItems, fmt.Sprintf("%v/ipv4-unicast/maximum-paths/ebgp", state.getPath())) + } if !state.Ipv4UnicastDistanceBgpLocal.IsNull() && data.Ipv4UnicastDistanceBgpLocal.IsNull() { deletedItems = append(deletedItems, fmt.Sprintf("%v/ipv4-unicast/distance/bgp/local", state.getPath())) } @@ -838,6 +876,12 @@ func (data *BGPAddressFamilyIPv4) getEmptyLeafsDelete(ctx context.Context) []str func (data *BGPAddressFamilyIPv4) getDeletePaths(ctx context.Context) []string { var deletePaths []string + if !data.Ipv4UnicastMaximumPathsIbgp.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/ipv4-unicast/maximum-paths/ibgp-leaf", data.getPath())) + } + if !data.Ipv4UnicastMaximumPathsEbgp.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/ipv4-unicast/maximum-paths/ebgp", data.getPath())) + } if !data.Ipv4UnicastDistanceBgpLocal.IsNull() { deletePaths = append(deletePaths, fmt.Sprintf("%v/ipv4-unicast/distance/bgp/local", data.getPath())) } diff --git a/internal/provider/model_iosxe_bgp_address_family_ipv4_vrf.go b/internal/provider/model_iosxe_bgp_address_family_ipv4_vrf.go index c90b55153..71f6ac539 100644 --- a/internal/provider/model_iosxe_bgp_address_family_ipv4_vrf.go +++ b/internal/provider/model_iosxe_bgp_address_family_ipv4_vrf.go @@ -68,6 +68,8 @@ type BGPAddressFamilyIPv4VRFVrfs struct { Ipv4UnicastDistanceBgpExternal types.Int64 `tfsdk:"ipv4_unicast_distance_bgp_external"` Ipv4UnicastDistanceBgpInternal types.Int64 `tfsdk:"ipv4_unicast_distance_bgp_internal"` Ipv4UnicastDistanceBgpLocal types.Int64 `tfsdk:"ipv4_unicast_distance_bgp_local"` + Ipv4UnicastMaximumPathsEbgp types.Int64 `tfsdk:"ipv4_unicast_maximum_paths_ebgp"` + Ipv4UnicastMaximumPathsIbgp types.Int64 `tfsdk:"ipv4_unicast_maximum_paths_ibgp"` } type BGPAddressFamilyIPv4VRFVrfsIpv4UnicastAggregateAddresses struct { Ipv4Address types.String `tfsdk:"ipv4_address"` @@ -161,6 +163,12 @@ func (data BGPAddressFamilyIPv4VRF) toBody(ctx context.Context) string { if !item.Ipv4UnicastDistanceBgpLocal.IsNull() && !item.Ipv4UnicastDistanceBgpLocal.IsUnknown() { body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf"+"."+strconv.Itoa(index)+"."+"ipv4-unicast.distance.bgp.local", strconv.FormatInt(item.Ipv4UnicastDistanceBgpLocal.ValueInt64(), 10)) } + if !item.Ipv4UnicastMaximumPathsEbgp.IsNull() && !item.Ipv4UnicastMaximumPathsEbgp.IsUnknown() { + body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf"+"."+strconv.Itoa(index)+"."+"ipv4-unicast.maximum-paths.ebgp", strconv.FormatInt(item.Ipv4UnicastMaximumPathsEbgp.ValueInt64(), 10)) + } + if !item.Ipv4UnicastMaximumPathsIbgp.IsNull() && !item.Ipv4UnicastMaximumPathsIbgp.IsUnknown() { + body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf"+"."+strconv.Itoa(index)+"."+"ipv4-unicast.maximum-paths.ibgp.max", strconv.FormatInt(item.Ipv4UnicastMaximumPathsIbgp.ValueInt64(), 10)) + } if len(item.Ipv4UnicastAggregateAddresses) > 0 { body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf"+"."+strconv.Itoa(index)+"."+"ipv4-unicast.aggregate-address", []interface{}{}) for cindex, citem := range item.Ipv4UnicastAggregateAddresses { @@ -520,6 +528,16 @@ func (data *BGPAddressFamilyIPv4VRF) updateFromBody(ctx context.Context, res gjs } else { data.Vrfs[i].Ipv4UnicastDistanceBgpLocal = types.Int64Null() } + if value := r.Get("ipv4-unicast.maximum-paths.ebgp"); value.Exists() && !data.Vrfs[i].Ipv4UnicastMaximumPathsEbgp.IsNull() { + data.Vrfs[i].Ipv4UnicastMaximumPathsEbgp = types.Int64Value(value.Int()) + } else { + data.Vrfs[i].Ipv4UnicastMaximumPathsEbgp = types.Int64Null() + } + if value := r.Get("ipv4-unicast.maximum-paths.ibgp.max"); value.Exists() && !data.Vrfs[i].Ipv4UnicastMaximumPathsIbgp.IsNull() { + data.Vrfs[i].Ipv4UnicastMaximumPathsIbgp = types.Int64Value(value.Int()) + } else { + data.Vrfs[i].Ipv4UnicastMaximumPathsIbgp = types.Int64Null() + } } } @@ -654,6 +672,12 @@ func (data *BGPAddressFamilyIPv4VRF) fromBody(ctx context.Context, res gjson.Res if cValue := v.Get("ipv4-unicast.distance.bgp.local"); cValue.Exists() { item.Ipv4UnicastDistanceBgpLocal = types.Int64Value(cValue.Int()) } + if cValue := v.Get("ipv4-unicast.maximum-paths.ebgp"); cValue.Exists() { + item.Ipv4UnicastMaximumPathsEbgp = types.Int64Value(cValue.Int()) + } + if cValue := v.Get("ipv4-unicast.maximum-paths.ibgp.max"); cValue.Exists() { + item.Ipv4UnicastMaximumPathsIbgp = types.Int64Value(cValue.Int()) + } data.Vrfs = append(data.Vrfs, item) return true }) @@ -791,6 +815,12 @@ func (data *BGPAddressFamilyIPv4VRFData) fromBody(ctx context.Context, res gjson if cValue := v.Get("ipv4-unicast.distance.bgp.local"); cValue.Exists() { item.Ipv4UnicastDistanceBgpLocal = types.Int64Value(cValue.Int()) } + if cValue := v.Get("ipv4-unicast.maximum-paths.ebgp"); cValue.Exists() { + item.Ipv4UnicastMaximumPathsEbgp = types.Int64Value(cValue.Int()) + } + if cValue := v.Get("ipv4-unicast.maximum-paths.ibgp.max"); cValue.Exists() { + item.Ipv4UnicastMaximumPathsIbgp = types.Int64Value(cValue.Int()) + } data.Vrfs = append(data.Vrfs, item) return true }) @@ -821,6 +851,12 @@ func (data *BGPAddressFamilyIPv4VRF) getDeletedItems(ctx context.Context, state found = false } if found { + if !state.Vrfs[i].Ipv4UnicastMaximumPathsIbgp.IsNull() && data.Vrfs[j].Ipv4UnicastMaximumPathsIbgp.IsNull() { + deletedItems = append(deletedItems, fmt.Sprintf("%v/vrf=%v/ipv4-unicast/maximum-paths/ibgp/max", state.getPath(), strings.Join(stateKeyValues[:], ","))) + } + if !state.Vrfs[i].Ipv4UnicastMaximumPathsEbgp.IsNull() && data.Vrfs[j].Ipv4UnicastMaximumPathsEbgp.IsNull() { + deletedItems = append(deletedItems, fmt.Sprintf("%v/vrf=%v/ipv4-unicast/maximum-paths/ebgp", state.getPath(), strings.Join(stateKeyValues[:], ","))) + } if !state.Vrfs[i].Ipv4UnicastDistanceBgpLocal.IsNull() && data.Vrfs[j].Ipv4UnicastDistanceBgpLocal.IsNull() { deletedItems = append(deletedItems, fmt.Sprintf("%v/vrf=%v/ipv4-unicast/distance/bgp/local", state.getPath(), strings.Join(stateKeyValues[:], ","))) } diff --git a/internal/provider/resource_iosxe_bgp_address_family_ipv4.go b/internal/provider/resource_iosxe_bgp_address_family_ipv4.go index b24abf0c9..28709fed7 100644 --- a/internal/provider/resource_iosxe_bgp_address_family_ipv4.go +++ b/internal/provider/resource_iosxe_bgp_address_family_ipv4.go @@ -240,6 +240,20 @@ func (r *BGPAddressFamilyIPv4Resource) Schema(ctx context.Context, req resource. int64validator.Between(1, 255), }, }, + "ipv4_unicast_maximum_paths_ebgp": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("eBGP-multipath").AddIntegerRangeDescription(1, 32).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(1, 32), + }, + }, + "ipv4_unicast_maximum_paths_ibgp": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("iBGP-multipath").AddIntegerRangeDescription(1, 32).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(1, 32), + }, + }, }, } } diff --git a/internal/provider/resource_iosxe_bgp_address_family_ipv4_test.go b/internal/provider/resource_iosxe_bgp_address_family_ipv4_test.go index 53ed99c8d..860669c27 100644 --- a/internal/provider/resource_iosxe_bgp_address_family_ipv4_test.go +++ b/internal/provider/resource_iosxe_bgp_address_family_ipv4_test.go @@ -52,6 +52,8 @@ func TestAccIosxeBGPAddressFamilyIPv4(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxe_bgp_address_family_ipv4.test", "ipv4_unicast_distance_bgp_external", "20")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_bgp_address_family_ipv4.test", "ipv4_unicast_distance_bgp_internal", "200")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_bgp_address_family_ipv4.test", "ipv4_unicast_distance_bgp_local", "200")) + checks = append(checks, resource.TestCheckResourceAttr("iosxe_bgp_address_family_ipv4.test", "ipv4_unicast_maximum_paths_ebgp", "2")) + checks = append(checks, resource.TestCheckResourceAttr("iosxe_bgp_address_family_ipv4.test", "ipv4_unicast_maximum_paths_ibgp", "2")) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, @@ -148,6 +150,8 @@ func testAccIosxeBGPAddressFamilyIPv4Config_all() string { config += ` ipv4_unicast_distance_bgp_external = 20` + "\n" config += ` ipv4_unicast_distance_bgp_internal = 200` + "\n" config += ` ipv4_unicast_distance_bgp_local = 200` + "\n" + config += ` ipv4_unicast_maximum_paths_ebgp = 2` + "\n" + config += ` ipv4_unicast_maximum_paths_ibgp = 2` + "\n" config += ` depends_on = [iosxe_restconf.PreReq0, ]` + "\n" config += `}` + "\n" return config diff --git a/internal/provider/resource_iosxe_bgp_address_family_ipv4_vrf.go b/internal/provider/resource_iosxe_bgp_address_family_ipv4_vrf.go index 0afc9058a..8fd421313 100644 --- a/internal/provider/resource_iosxe_bgp_address_family_ipv4_vrf.go +++ b/internal/provider/resource_iosxe_bgp_address_family_ipv4_vrf.go @@ -275,6 +275,20 @@ func (r *BGPAddressFamilyIPv4VRFResource) Schema(ctx context.Context, req resour int64validator.Between(1, 255), }, }, + "ipv4_unicast_maximum_paths_ebgp": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("eBGP-multipath").AddIntegerRangeDescription(1, 32).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(1, 32), + }, + }, + "ipv4_unicast_maximum_paths_ibgp": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("").AddIntegerRangeDescription(1, 32).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(1, 32), + }, + }, }, }, }, diff --git a/internal/provider/resource_iosxe_bgp_address_family_ipv4_vrf_test.go b/internal/provider/resource_iosxe_bgp_address_family_ipv4_vrf_test.go index 339a99ebc..82db2c723 100644 --- a/internal/provider/resource_iosxe_bgp_address_family_ipv4_vrf_test.go +++ b/internal/provider/resource_iosxe_bgp_address_family_ipv4_vrf_test.go @@ -55,6 +55,8 @@ func TestAccIosxeBGPAddressFamilyIPv4VRF(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxe_bgp_address_family_ipv4_vrf.test", "vrfs.0.ipv4_unicast_distance_bgp_external", "20")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_bgp_address_family_ipv4_vrf.test", "vrfs.0.ipv4_unicast_distance_bgp_internal", "200")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_bgp_address_family_ipv4_vrf.test", "vrfs.0.ipv4_unicast_distance_bgp_local", "200")) + checks = append(checks, resource.TestCheckResourceAttr("iosxe_bgp_address_family_ipv4_vrf.test", "vrfs.0.ipv4_unicast_maximum_paths_ebgp", "2")) + checks = append(checks, resource.TestCheckResourceAttr("iosxe_bgp_address_family_ipv4_vrf.test", "vrfs.0.ipv4_unicast_maximum_paths_ibgp", "2")) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, @@ -174,6 +176,8 @@ func testAccIosxeBGPAddressFamilyIPv4VRFConfig_all() string { config += ` ipv4_unicast_distance_bgp_external = 20` + "\n" config += ` ipv4_unicast_distance_bgp_internal = 200` + "\n" config += ` ipv4_unicast_distance_bgp_local = 200` + "\n" + config += ` ipv4_unicast_maximum_paths_ebgp = 2` + "\n" + config += ` ipv4_unicast_maximum_paths_ibgp = 2` + "\n" config += ` }]` + "\n" config += ` depends_on = [iosxe_restconf.PreReq0, iosxe_restconf.PreReq1, iosxe_restconf.PreReq2, ]` + "\n" config += `}` + "\n" diff --git a/templates/guides/changelog.md.tmpl b/templates/guides/changelog.md.tmpl index b072ae6e6..50baf7788 100644 --- a/templates/guides/changelog.md.tmpl +++ b/templates/guides/changelog.md.tmpl @@ -19,6 +19,7 @@ description: |- - Add `iosxe_bgp_template_peer_policy` resource - Add `ip_dhcp_relay_information_option_vpn_id` attribute to `iosxe_interface_ethernet` resource and `iosxe_interface_vlan` resource - Add `local_routing` attribute to `iosxe_interface_nve` resource and data source +- Add `ipv4_unicast_maximum_paths_ebgp` and `ipv4_unicast_maximum_paths_ibgp` attributes to the `iosxe_bgp_address_family_ipv4` and `iosxe_bgp_address_family_ipv4_vrf` resources ## 0.9.3