diff --git a/docs/data-sources/interface_port_channel.md b/docs/data-sources/interface_port_channel.md index f01db06c..8be779e6 100644 --- a/docs/data-sources/interface_port_channel.md +++ b/docs/data-sources/interface_port_channel.md @@ -61,6 +61,7 @@ data "iosxe_interface_port_channel" "example" { - `ip_arp_inspection_limit_rate` (Number) Rate Limit - `ip_arp_inspection_trust` (Boolean) Configure Trust state - `ip_dhcp_relay_source_interface` (String) Set source interface for relayed messages +- `ip_dhcp_snooping_trust` (Boolean) DHCP Snooping trust config - `ip_proxy_arp` (Boolean) Enable proxy ARP - `ip_redirects` (Boolean) Enable sending ICMP Redirect messages - `ip_unreachables` (Boolean) Enable sending ICMP Unreachable messages @@ -75,6 +76,7 @@ data "iosxe_interface_port_channel" "example" { - `ipv6_nd_ra_suppress_all` (Boolean) Suppress all IPv6 RA - `shutdown` (Boolean) Shutdown the selected interface - `spanning_tree_guard` (String) Change an interface's spanning tree guard mode +- `spanning_tree_link_type` (String) Specify a link type for spanning tree tree protocol use - `switchport` (Boolean) - `trust_device` (String) trusted device class - `vrf_forwarding` (String) Configure forwarding table diff --git a/docs/resources/interface_port_channel.md b/docs/resources/interface_port_channel.md index 1ff80d4f..6ed1f9a3 100644 --- a/docs/resources/interface_port_channel.md +++ b/docs/resources/interface_port_channel.md @@ -37,13 +37,13 @@ resource "iosxe_interface_port_channel" "example" { ipv6_address_dhcp = true ipv6_link_local_addresses = [ { - address = "fe80::9656:d028:8652:66b9" + address = "fe80::64" link_local = true } ] ipv6_addresses = [ { - prefix = "2004:DB8::/32" + prefix = "2224:DB8::/32" eui_64 = true } ] @@ -96,6 +96,7 @@ resource "iosxe_interface_port_channel" "example" { - Range: `0`-`4294967295` - `ip_arp_inspection_trust` (Boolean) Configure Trust state - `ip_dhcp_relay_source_interface` (String) Set source interface for relayed messages +- `ip_dhcp_snooping_trust` (Boolean) DHCP Snooping trust config - `ip_proxy_arp` (Boolean) Enable proxy ARP - `ip_redirects` (Boolean) Enable sending ICMP Redirect messages - `ip_unreachables` (Boolean) Enable sending ICMP Unreachable messages @@ -112,6 +113,8 @@ resource "iosxe_interface_port_channel" "example" { - `shutdown` (Boolean) Shutdown the selected interface - `spanning_tree_guard` (String) Change an interface's spanning tree guard mode - Choices: `loop`, `none`, `root` +- `spanning_tree_link_type` (String) Specify a link type for spanning tree tree protocol use + - Choices: `point-to-point`, `shared` - `switchport` (Boolean) - `trust_device` (String) trusted device class - Choices: `cisco-phone`, `cts`, `ip-camera`, `media-player` diff --git a/examples/resources/iosxe_interface_port_channel/resource.tf b/examples/resources/iosxe_interface_port_channel/resource.tf index 3a81f681..302f6155 100644 --- a/examples/resources/iosxe_interface_port_channel/resource.tf +++ b/examples/resources/iosxe_interface_port_channel/resource.tf @@ -22,13 +22,13 @@ resource "iosxe_interface_port_channel" "example" { ipv6_address_dhcp = true ipv6_link_local_addresses = [ { - address = "fe80::9656:d028:8652:66b9" + address = "fe80::64" link_local = true } ] ipv6_addresses = [ { - prefix = "2004:DB8::/32" + prefix = "2224:DB8::/32" eui_64 = true } ] diff --git a/gen/definitions/interface_port_channel.yaml b/gen/definitions/interface_port_channel.yaml index 73d0b79d..a5c2e31e 100644 --- a/gen/definitions/interface_port_channel.yaml +++ b/gen/definitions/interface_port_channel.yaml @@ -33,6 +33,7 @@ attributes: - yang_name: switchport-conf/switchport tf_name: switchport example: false + exclude_test: true test_tags: [C9000V] - yang_name: ip/access-group/in/apply-type/apply-intf/acl/acl-name xpath: ip/access-group/in/acl/acl-name @@ -164,7 +165,7 @@ attributes: attributes: - yang_name: address id: true - example: fe80::9656:d028:8652:66b9 + example: fe80::64 - yang_name: link-local example: true - yang_name: ipv6/address/prefix-list @@ -173,16 +174,26 @@ attributes: attributes: - yang_name: prefix id: true - example: 2004:DB8::/32 + example: 2224:DB8::/32 - yang_name: eui-64 example: true - yang_name: arp/timeout example: 2147 - yang_name: ip/arp/inspection/trust example: true + exclude_test: true test_tags: [C9000V] - yang_name: ip/arp/inspection/limit/rate example: 1000 + exclude_test: true + test_tags: [C9000V] + - yang_name: Cisco-IOS-XE-spanning-tree:spanning-tree/link-type + example: point-to-point + exclude_test: true + test_tags: [C9000V] + - yang_name: ip/dhcp/Cisco-IOS-XE-dhcp:snooping/trust + example: true + exclude_test: true test_tags: [C9000V] test_prerequisites: diff --git a/internal/provider/data_source_iosxe_interface_port_channel.go b/internal/provider/data_source_iosxe_interface_port_channel.go index 84a87527..2d872883 100644 --- a/internal/provider/data_source_iosxe_interface_port_channel.go +++ b/internal/provider/data_source_iosxe_interface_port_channel.go @@ -291,6 +291,14 @@ func (d *InterfacePortChannelDataSource) Schema(ctx context.Context, req datasou MarkdownDescription: "Rate Limit", Computed: true, }, + "spanning_tree_link_type": schema.StringAttribute{ + MarkdownDescription: "Specify a link type for spanning tree tree protocol use", + Computed: true, + }, + "ip_dhcp_snooping_trust": schema.BoolAttribute{ + MarkdownDescription: "DHCP Snooping trust config", + Computed: true, + }, }, } } diff --git a/internal/provider/data_source_iosxe_interface_port_channel_test.go b/internal/provider/data_source_iosxe_interface_port_channel_test.go index 4a7804b4..b0804fb1 100644 --- a/internal/provider/data_source_iosxe_interface_port_channel_test.go +++ b/internal/provider/data_source_iosxe_interface_port_channel_test.go @@ -42,9 +42,6 @@ func TestAccDataSourceIosxeInterfacePortChannel(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "vrf_forwarding", "VRF1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ipv4_address", "192.0.2.1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ipv4_address_mask", "255.255.255.0")) - if os.Getenv("C9000V") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "switchport", "false")) - } checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ip_access_group_in", "1")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ip_access_group_in_enable", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ip_access_group_out", "1")) @@ -65,17 +62,11 @@ func TestAccDataSourceIosxeInterfacePortChannel(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ipv6_mtu", "1300")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ipv6_nd_ra_suppress_all", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ipv6_address_dhcp", "true")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ipv6_link_local_addresses.0.address", "fe80::9656:d028:8652:66b9")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ipv6_link_local_addresses.0.address", "fe80::64")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ipv6_link_local_addresses.0.link_local", "true")) - checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ipv6_addresses.0.prefix", "2004:DB8::/32")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ipv6_addresses.0.prefix", "2224:DB8::/32")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ipv6_addresses.0.eui_64", "true")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "arp_timeout", "2147")) - if os.Getenv("C9000V") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ip_arp_inspection_trust", "true")) - } - if os.Getenv("C9000V") != "" { - checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_interface_port_channel.test", "ip_arp_inspection_limit_rate", "1000")) - } resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, @@ -118,9 +109,6 @@ func testAccDataSourceIosxeInterfacePortChannelConfig() string { config += ` vrf_forwarding = "VRF1"` + "\n" config += ` ipv4_address = "192.0.2.1"` + "\n" config += ` ipv4_address_mask = "255.255.255.0"` + "\n" - if os.Getenv("C9000V") != "" { - config += ` switchport = false` + "\n" - } config += ` ip_access_group_in = "1"` + "\n" config += ` ip_access_group_in_enable = true` + "\n" config += ` ip_access_group_out = "1"` + "\n" @@ -144,20 +132,14 @@ func testAccDataSourceIosxeInterfacePortChannelConfig() string { config += ` ipv6_nd_ra_suppress_all = true` + "\n" config += ` ipv6_address_dhcp = true` + "\n" config += ` ipv6_link_local_addresses = [{` + "\n" - config += ` address = "fe80::9656:d028:8652:66b9"` + "\n" + config += ` address = "fe80::64"` + "\n" config += ` link_local = true` + "\n" config += ` }]` + "\n" config += ` ipv6_addresses = [{` + "\n" - config += ` prefix = "2004:DB8::/32"` + "\n" + config += ` prefix = "2224:DB8::/32"` + "\n" config += ` eui_64 = true` + "\n" config += ` }]` + "\n" config += ` arp_timeout = 2147` + "\n" - if os.Getenv("C9000V") != "" { - config += ` ip_arp_inspection_trust = true` + "\n" - } - if os.Getenv("C9000V") != "" { - config += ` ip_arp_inspection_limit_rate = 1000` + "\n" - } config += ` depends_on = [iosxe_restconf.PreReq0, ]` + "\n" config += `}` + "\n" diff --git a/internal/provider/model_iosxe_interface_port_channel.go b/internal/provider/model_iosxe_interface_port_channel.go index 4bcd0554..18e232d4 100644 --- a/internal/provider/model_iosxe_interface_port_channel.go +++ b/internal/provider/model_iosxe_interface_port_channel.go @@ -85,6 +85,8 @@ type InterfacePortChannel struct { ArpTimeout types.Int64 `tfsdk:"arp_timeout"` IpArpInspectionTrust types.Bool `tfsdk:"ip_arp_inspection_trust"` IpArpInspectionLimitRate types.Int64 `tfsdk:"ip_arp_inspection_limit_rate"` + SpanningTreeLinkType types.String `tfsdk:"spanning_tree_link_type"` + IpDhcpSnoopingTrust types.Bool `tfsdk:"ip_dhcp_snooping_trust"` } type InterfacePortChannelData struct { @@ -137,6 +139,8 @@ type InterfacePortChannelData struct { ArpTimeout types.Int64 `tfsdk:"arp_timeout"` IpArpInspectionTrust types.Bool `tfsdk:"ip_arp_inspection_trust"` IpArpInspectionLimitRate types.Int64 `tfsdk:"ip_arp_inspection_limit_rate"` + SpanningTreeLinkType types.String `tfsdk:"spanning_tree_link_type"` + IpDhcpSnoopingTrust types.Bool `tfsdk:"ip_dhcp_snooping_trust"` } type InterfacePortChannelHelperAddresses struct { Address types.String `tfsdk:"address"` @@ -345,6 +349,14 @@ func (data InterfacePortChannel) toBody(ctx context.Context) string { if !data.IpArpInspectionLimitRate.IsNull() && !data.IpArpInspectionLimitRate.IsUnknown() { body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ip.arp.inspection.limit.rate", strconv.FormatInt(data.IpArpInspectionLimitRate.ValueInt64(), 10)) } + if !data.SpanningTreeLinkType.IsNull() && !data.SpanningTreeLinkType.IsUnknown() { + body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"Cisco-IOS-XE-spanning-tree:spanning-tree.link-type", data.SpanningTreeLinkType.ValueString()) + } + if !data.IpDhcpSnoopingTrust.IsNull() && !data.IpDhcpSnoopingTrust.IsUnknown() { + if data.IpDhcpSnoopingTrust.ValueBool() { + body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ip.dhcp.Cisco-IOS-XE-dhcp:snooping.trust", map[string]string{}) + } + } if len(data.HelperAddresses) > 0 { body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ip.helper-address", []interface{}{}) for index, item := range data.HelperAddresses { @@ -826,6 +838,20 @@ func (data *InterfacePortChannel) updateFromBody(ctx context.Context, res gjson. } else { data.IpArpInspectionLimitRate = types.Int64Null() } + if value := res.Get(prefix + "Cisco-IOS-XE-spanning-tree:spanning-tree.link-type"); value.Exists() && !data.SpanningTreeLinkType.IsNull() { + data.SpanningTreeLinkType = types.StringValue(value.String()) + } else { + data.SpanningTreeLinkType = types.StringNull() + } + if value := res.Get(prefix + "ip.dhcp.Cisco-IOS-XE-dhcp:snooping.trust"); !data.IpDhcpSnoopingTrust.IsNull() { + if value.Exists() { + data.IpDhcpSnoopingTrust = types.BoolValue(true) + } else { + data.IpDhcpSnoopingTrust = types.BoolValue(false) + } + } else { + data.IpDhcpSnoopingTrust = types.BoolNull() + } } func (data *InterfacePortChannelData) fromBody(ctx context.Context, res gjson.Result) { @@ -1065,6 +1091,14 @@ func (data *InterfacePortChannelData) fromBody(ctx context.Context, res gjson.Re if value := res.Get(prefix + "ip.arp.inspection.limit.rate"); value.Exists() { data.IpArpInspectionLimitRate = types.Int64Value(value.Int()) } + if value := res.Get(prefix + "Cisco-IOS-XE-spanning-tree:spanning-tree.link-type"); value.Exists() { + data.SpanningTreeLinkType = types.StringValue(value.String()) + } + if value := res.Get(prefix + "ip.dhcp.Cisco-IOS-XE-dhcp:snooping.trust"); value.Exists() { + data.IpDhcpSnoopingTrust = types.BoolValue(true) + } else { + data.IpDhcpSnoopingTrust = types.BoolValue(false) + } } func (data *InterfacePortChannel) getDeletedListItems(ctx context.Context, state InterfacePortChannel) []string { @@ -1230,6 +1264,9 @@ func (data *InterfacePortChannel) getEmptyLeafsDelete(ctx context.Context) []str if !data.IpArpInspectionTrust.IsNull() && !data.IpArpInspectionTrust.ValueBool() { emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/ip/arp/inspection/trust", data.getPath())) } + if !data.IpDhcpSnoopingTrust.IsNull() && !data.IpDhcpSnoopingTrust.ValueBool() { + emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/ip/dhcp/Cisco-IOS-XE-dhcp:snooping/trust", data.getPath())) + } return emptyLeafsDelete } @@ -1379,5 +1416,11 @@ func (data *InterfacePortChannel) getDeletePaths(ctx context.Context) []string { if !data.IpArpInspectionLimitRate.IsNull() { deletePaths = append(deletePaths, fmt.Sprintf("%v/ip/arp/inspection/limit/rate", data.getPath())) } + if !data.SpanningTreeLinkType.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/Cisco-IOS-XE-spanning-tree:spanning-tree/link-type", data.getPath())) + } + if !data.IpDhcpSnoopingTrust.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/ip/dhcp/Cisco-IOS-XE-dhcp:snooping/trust", data.getPath())) + } return deletePaths } diff --git a/internal/provider/resource_iosxe_interface_port_channel.go b/internal/provider/resource_iosxe_interface_port_channel.go index 33c30de0..85d02f7f 100644 --- a/internal/provider/resource_iosxe_interface_port_channel.go +++ b/internal/provider/resource_iosxe_interface_port_channel.go @@ -354,6 +354,17 @@ func (r *InterfacePortChannelResource) Schema(ctx context.Context, req resource. int64validator.Between(0, 4294967295), }, }, + "spanning_tree_link_type": schema.StringAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Specify a link type for spanning tree tree protocol use").AddStringEnumDescription("point-to-point", "shared").String, + Optional: true, + Validators: []validator.String{ + stringvalidator.OneOf("point-to-point", "shared"), + }, + }, + "ip_dhcp_snooping_trust": schema.BoolAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("DHCP Snooping trust config").String, + Optional: true, + }, }, } } diff --git a/internal/provider/resource_iosxe_interface_port_channel_test.go b/internal/provider/resource_iosxe_interface_port_channel_test.go index 94e1bbc6..1a4e719f 100644 --- a/internal/provider/resource_iosxe_interface_port_channel_test.go +++ b/internal/provider/resource_iosxe_interface_port_channel_test.go @@ -43,9 +43,6 @@ func TestAccIosxeInterfacePortChannel(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "vrf_forwarding", "VRF1")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ipv4_address", "192.0.2.1")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ipv4_address_mask", "255.255.255.0")) - if os.Getenv("C9000V") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "switchport", "false")) - } checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ip_access_group_in", "1")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ip_access_group_in_enable", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ip_access_group_out", "1")) @@ -66,17 +63,11 @@ func TestAccIosxeInterfacePortChannel(t *testing.T) { checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ipv6_mtu", "1300")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ipv6_nd_ra_suppress_all", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ipv6_address_dhcp", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ipv6_link_local_addresses.0.address", "fe80::9656:d028:8652:66b9")) + checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ipv6_link_local_addresses.0.address", "fe80::64")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ipv6_link_local_addresses.0.link_local", "true")) - checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ipv6_addresses.0.prefix", "2004:DB8::/32")) + checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ipv6_addresses.0.prefix", "2224:DB8::/32")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ipv6_addresses.0.eui_64", "true")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "arp_timeout", "2147")) - if os.Getenv("C9000V") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ip_arp_inspection_trust", "true")) - } - if os.Getenv("C9000V") != "" { - checks = append(checks, resource.TestCheckResourceAttr("iosxe_interface_port_channel.test", "ip_arp_inspection_limit_rate", "1000")) - } resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, @@ -134,9 +125,6 @@ func testAccIosxeInterfacePortChannelConfig_all() string { config += ` vrf_forwarding = "VRF1"` + "\n" config += ` ipv4_address = "192.0.2.1"` + "\n" config += ` ipv4_address_mask = "255.255.255.0"` + "\n" - if os.Getenv("C9000V") != "" { - config += ` switchport = false` + "\n" - } config += ` ip_access_group_in = "1"` + "\n" config += ` ip_access_group_in_enable = true` + "\n" config += ` ip_access_group_out = "1"` + "\n" @@ -160,20 +148,14 @@ func testAccIosxeInterfacePortChannelConfig_all() string { config += ` ipv6_nd_ra_suppress_all = true` + "\n" config += ` ipv6_address_dhcp = true` + "\n" config += ` ipv6_link_local_addresses = [{` + "\n" - config += ` address = "fe80::9656:d028:8652:66b9"` + "\n" + config += ` address = "fe80::64"` + "\n" config += ` link_local = true` + "\n" config += ` }]` + "\n" config += ` ipv6_addresses = [{` + "\n" - config += ` prefix = "2004:DB8::/32"` + "\n" + config += ` prefix = "2224:DB8::/32"` + "\n" config += ` eui_64 = true` + "\n" config += ` }]` + "\n" config += ` arp_timeout = 2147` + "\n" - if os.Getenv("C9000V") != "" { - config += ` ip_arp_inspection_trust = true` + "\n" - } - if os.Getenv("C9000V") != "" { - config += ` ip_arp_inspection_limit_rate = 1000` + "\n" - } config += ` depends_on = [iosxe_restconf.PreReq0, ]` + "\n" config += `}` + "\n" return config