From 979b88892badb4568abddaf23d4d0ac0bd0bda07 Mon Sep 17 00:00:00 2001 From: Cameron Schaeffer Date: Fri, 31 Oct 2025 11:15:36 +0000 Subject: [PATCH 1/3] feat: add IP SSH bulk-mode support to system resource - Add ip_ssh_bulk_mode boolean attribute to enable SSH bulk-mode - Add ip_ssh_bulk_mode_window_size attribute (range: 131072-1073741824 bytes) - Update CHANGELOG.md with new attributes - Generate provider code, tests, examples, and documentation YANG Model Reference: - Path: /native/ip/ssh/bulk-mode - File: Cisco-IOS-XE-ip.yang (lines 4598-4610) - Type: Presence container with optional window-size leaf CLI Commands Enabled: - ip ssh bulk-mode - ip ssh bulk-mode window-size --- CHANGELOG.md | 1 + docs/data-sources/system.md | 2 + docs/guides/changelog.md | 1 + docs/resources/system.md | 5 ++ examples/resources/iosxe_system/resource.tf | 2 + gen/definitions/system.yaml | 4 ++ internal/provider/data_source_iosxe_system.go | 8 +++ .../provider/data_source_iosxe_system_test.go | 4 ++ internal/provider/model_iosxe_system.go | 57 +++++++++++++++++++ internal/provider/resource_iosxe_system.go | 11 ++++ .../provider/resource_iosxe_system_test.go | 4 ++ templates/guides/changelog.md.tmpl | 1 + 12 files changed, 100 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b58fc93c..43ac9cac8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Add `ip_domain_lookup_nsap`, `ip_domain_lookup_recursive`, and `ip_domain_lookup_vrfs*` attributes to `iosxe_system` resource and data source - Add `iosxe_evpn_ethernet_segment` resource and data source for managing L2VPN EVPN Ethernet Segment configuration - Add `evpn_ethernet_segments` attribute to `iosxe_interface_ethernet` and `iosxe_interface_port_channel` resources and data sources +- Add `ip_ssh_bulk_mode` and `ip_ssh_bulk_mode_window_size` attributes to `iosxe_system` resource and data source ## 0.9.3 diff --git a/docs/data-sources/system.md b/docs/data-sources/system.md index bd930d809..8f300783c 100644 --- a/docs/data-sources/system.md +++ b/docs/data-sources/system.md @@ -107,6 +107,8 @@ data "iosxe_system" "example" { - `ip_scp_server_enable` (Boolean) Enable server side of SCP - `ip_source_route` (Boolean) Process packets with source routing header options - `ip_ssh_authentication_retries` (Number) Specify number of authentication retries +- `ip_ssh_bulk_mode` (Boolean) Enable optimizations for bulk data transfer procedures +- `ip_ssh_bulk_mode_window_size` (Number) Window-size value - `ip_ssh_source_interface_five_gigabit_ethernet` (String) Five GigabitEthernet - `ip_ssh_source_interface_forty_gigabit_ethernet` (String) Forty GigabitEthernet - `ip_ssh_source_interface_gigabit_ethernet` (String) GigabitEthernet IEEE 802.3z diff --git a/docs/guides/changelog.md b/docs/guides/changelog.md index 9b08bc539..b16c51b92 100644 --- a/docs/guides/changelog.md +++ b/docs/guides/changelog.md @@ -13,6 +13,7 @@ description: |- - Add `ip_domain_lookup_nsap`, `ip_domain_lookup_recursive`, and `ip_domain_lookup_vrfs*` attributes to `iosxe_system` resource and data source - Add `iosxe_evpn_ethernet_segment` resource and data source for managing L2VPN EVPN Ethernet Segment configuration - Add `evpn_ethernet_segments` attribute to `iosxe_interface_ethernet` and `iosxe_interface_port_channel` resources and data sources +- Add `ip_ssh_bulk_mode` and `ip_ssh_bulk_mode_window_size` attributes to `iosxe_system` resource and data source ## 0.9.3 diff --git a/docs/resources/system.md b/docs/resources/system.md index fca0753db..aa7abd6ab 100644 --- a/docs/resources/system.md +++ b/docs/resources/system.md @@ -49,6 +49,8 @@ resource "iosxe_system" "example" { memory_free_low_watermark_processor = 203038 ip_ssh_time_out = 120 ip_ssh_authentication_retries = 3 + ip_ssh_bulk_mode = true + ip_ssh_bulk_mode_window_size = 262144 call_home_contact_email = "email@test.com" call_home_cisco_tac_1_profile_active = true call_home_cisco_tac_1_destination_transport_method = "email" @@ -163,6 +165,9 @@ resource "iosxe_system" "example" { - `ip_source_route` (Boolean) Process packets with source routing header options - `ip_ssh_authentication_retries` (Number) Specify number of authentication retries - Range: `0`-`5` +- `ip_ssh_bulk_mode` (Boolean) Enable optimizations for bulk data transfer procedures +- `ip_ssh_bulk_mode_window_size` (Number) Window-size value + - Range: `131072`-`1073741824` - `ip_ssh_source_interface_five_gigabit_ethernet` (String) Five GigabitEthernet - `ip_ssh_source_interface_forty_gigabit_ethernet` (String) Forty GigabitEthernet - `ip_ssh_source_interface_gigabit_ethernet` (String) GigabitEthernet IEEE 802.3z diff --git a/examples/resources/iosxe_system/resource.tf b/examples/resources/iosxe_system/resource.tf index 9260259f2..7fef0c430 100644 --- a/examples/resources/iosxe_system/resource.tf +++ b/examples/resources/iosxe_system/resource.tf @@ -34,6 +34,8 @@ resource "iosxe_system" "example" { memory_free_low_watermark_processor = 203038 ip_ssh_time_out = 120 ip_ssh_authentication_retries = 3 + ip_ssh_bulk_mode = true + ip_ssh_bulk_mode_window_size = 262144 call_home_contact_email = "email@test.com" call_home_cisco_tac_1_profile_active = true call_home_cisco_tac_1_destination_transport_method = "email" diff --git a/gen/definitions/system.yaml b/gen/definitions/system.yaml index 2f8a6f792..2e58d164f 100644 --- a/gen/definitions/system.yaml +++ b/gen/definitions/system.yaml @@ -343,6 +343,10 @@ attributes: tf_name: ip_ssh_source_interface_hundred_gigabit_ethernet example: 1 exclude_test: true + - yang_name: ip/ssh/bulk-mode + example: true + - yang_name: ip/ssh/bulk-mode/window-size + example: 262144 - yang_name: control-plane/Cisco-IOS-XE-policy:service-policy/input example: system-cpp-policy exclude_test: true diff --git a/internal/provider/data_source_iosxe_system.go b/internal/provider/data_source_iosxe_system.go index 1ef5ce3b0..dab972419 100644 --- a/internal/provider/data_source_iosxe_system.go +++ b/internal/provider/data_source_iosxe_system.go @@ -449,6 +449,14 @@ func (d *SystemDataSource) Schema(ctx context.Context, req datasource.SchemaRequ MarkdownDescription: "Hundred GigabitEthernet", Computed: true, }, + "ip_ssh_bulk_mode": schema.BoolAttribute{ + MarkdownDescription: "Enable optimizations for bulk data transfer procedures", + Computed: true, + }, + "ip_ssh_bulk_mode_window_size": schema.Int64Attribute{ + MarkdownDescription: "Window-size value", + Computed: true, + }, "control_plane_service_policy_input": schema.StringAttribute{ MarkdownDescription: "Assign policy-map to the input of an interface", Computed: true, diff --git a/internal/provider/data_source_iosxe_system_test.go b/internal/provider/data_source_iosxe_system_test.go index e7e36085a..10c617143 100644 --- a/internal/provider/data_source_iosxe_system_test.go +++ b/internal/provider/data_source_iosxe_system_test.go @@ -71,6 +71,8 @@ func TestAccDataSourceIosxeSystem(t *testing.T) { } checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_system.test", "ip_ssh_time_out", "120")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_system.test", "ip_ssh_authentication_retries", "3")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_system.test", "ip_ssh_bulk_mode", "true")) + checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_system.test", "ip_ssh_bulk_mode_window_size", "262144")) if os.Getenv("IOSXE1715") != "" { checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_system.test", "ip_hosts.0.name", "test.router.com")) checks = append(checks, resource.TestCheckResourceAttr("data.iosxe_system.test", "ip_hosts.0.ips.0", "3.3.3.3")) @@ -159,6 +161,8 @@ func testAccDataSourceIosxeSystemConfig() string { } config += ` ip_ssh_time_out = 120` + "\n" config += ` ip_ssh_authentication_retries = 3` + "\n" + config += ` ip_ssh_bulk_mode = true` + "\n" + config += ` ip_ssh_bulk_mode_window_size = 262144` + "\n" if os.Getenv("IOSXE1715") != "" { config += ` ip_hosts = [{` + "\n" config += ` name = "test.router.com"` + "\n" diff --git a/internal/provider/model_iosxe_system.go b/internal/provider/model_iosxe_system.go index e42d581c4..a2341293e 100644 --- a/internal/provider/model_iosxe_system.go +++ b/internal/provider/model_iosxe_system.go @@ -115,6 +115,8 @@ type System struct { IpSshSourceInterfaceTwentyFiveGigabitEthernet types.String `tfsdk:"ip_ssh_source_interface_twenty_five_gigabit_ethernet"` IpSshSourceInterfaceFortyGigabitEthernet types.String `tfsdk:"ip_ssh_source_interface_forty_gigabit_ethernet"` IpSshSourceInterfaceHundredGigabitEthernet types.String `tfsdk:"ip_ssh_source_interface_hundred_gigabit_ethernet"` + IpSshBulkMode types.Bool `tfsdk:"ip_ssh_bulk_mode"` + IpSshBulkModeWindowSize types.Int64 `tfsdk:"ip_ssh_bulk_mode_window_size"` ControlPlaneServicePolicyInput types.String `tfsdk:"control_plane_service_policy_input"` PnpProfiles []SystemPnpProfiles `tfsdk:"pnp_profiles"` IpTacacsSourceInterfaceLoopback types.Int64 `tfsdk:"ip_tacacs_source_interface_loopback"` @@ -252,6 +254,8 @@ type SystemData struct { IpSshSourceInterfaceTwentyFiveGigabitEthernet types.String `tfsdk:"ip_ssh_source_interface_twenty_five_gigabit_ethernet"` IpSshSourceInterfaceFortyGigabitEthernet types.String `tfsdk:"ip_ssh_source_interface_forty_gigabit_ethernet"` IpSshSourceInterfaceHundredGigabitEthernet types.String `tfsdk:"ip_ssh_source_interface_hundred_gigabit_ethernet"` + IpSshBulkMode types.Bool `tfsdk:"ip_ssh_bulk_mode"` + IpSshBulkModeWindowSize types.Int64 `tfsdk:"ip_ssh_bulk_mode_window_size"` ControlPlaneServicePolicyInput types.String `tfsdk:"control_plane_service_policy_input"` PnpProfiles []SystemPnpProfiles `tfsdk:"pnp_profiles"` IpTacacsSourceInterfaceLoopback types.Int64 `tfsdk:"ip_tacacs_source_interface_loopback"` @@ -649,6 +653,14 @@ func (data System) toBody(ctx context.Context) string { if !data.IpSshSourceInterfaceHundredGigabitEthernet.IsNull() && !data.IpSshSourceInterfaceHundredGigabitEthernet.IsUnknown() { body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ip.ssh.source-interface-config.HundredGigE", data.IpSshSourceInterfaceHundredGigabitEthernet.ValueString()) } + if !data.IpSshBulkMode.IsNull() && !data.IpSshBulkMode.IsUnknown() { + if data.IpSshBulkMode.ValueBool() { + body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ip.ssh.bulk-mode", map[string]string{}) + } + } + if !data.IpSshBulkModeWindowSize.IsNull() && !data.IpSshBulkModeWindowSize.IsUnknown() { + body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ip.ssh.bulk-mode.window-size", strconv.FormatInt(data.IpSshBulkModeWindowSize.ValueInt64(), 10)) + } if !data.ControlPlaneServicePolicyInput.IsNull() && !data.ControlPlaneServicePolicyInput.IsUnknown() { body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"control-plane.Cisco-IOS-XE-policy:service-policy.input", data.ControlPlaneServicePolicyInput.ValueString()) } @@ -1601,6 +1613,20 @@ func (data *System) updateFromBody(ctx context.Context, res gjson.Result) { } else { data.IpSshSourceInterfaceHundredGigabitEthernet = types.StringNull() } + if value := res.Get(prefix + "ip.ssh.bulk-mode"); !data.IpSshBulkMode.IsNull() { + if value.Exists() { + data.IpSshBulkMode = types.BoolValue(true) + } else { + data.IpSshBulkMode = types.BoolValue(false) + } + } else { + data.IpSshBulkMode = types.BoolNull() + } + if value := res.Get(prefix + "ip.ssh.bulk-mode.window-size"); value.Exists() && !data.IpSshBulkModeWindowSize.IsNull() { + data.IpSshBulkModeWindowSize = types.Int64Value(value.Int()) + } else { + data.IpSshBulkModeWindowSize = types.Int64Null() + } if value := res.Get(prefix + "control-plane.Cisco-IOS-XE-policy:service-policy.input"); value.Exists() && !data.ControlPlaneServicePolicyInput.IsNull() { data.ControlPlaneServicePolicyInput = types.StringValue(value.String()) } else { @@ -2459,6 +2485,14 @@ func (data *System) fromBody(ctx context.Context, res gjson.Result) { if value := res.Get(prefix + "ip.ssh.source-interface-config.HundredGigE"); value.Exists() { data.IpSshSourceInterfaceHundredGigabitEthernet = types.StringValue(value.String()) } + if value := res.Get(prefix + "ip.ssh.bulk-mode"); value.Exists() { + data.IpSshBulkMode = types.BoolValue(true) + } else { + data.IpSshBulkMode = types.BoolValue(false) + } + if value := res.Get(prefix + "ip.ssh.bulk-mode.window-size"); value.Exists() { + data.IpSshBulkModeWindowSize = types.Int64Value(value.Int()) + } if value := res.Get(prefix + "control-plane.Cisco-IOS-XE-policy:service-policy.input"); value.Exists() { data.ControlPlaneServicePolicyInput = types.StringValue(value.String()) } @@ -3089,6 +3123,14 @@ func (data *SystemData) fromBody(ctx context.Context, res gjson.Result) { if value := res.Get(prefix + "ip.ssh.source-interface-config.HundredGigE"); value.Exists() { data.IpSshSourceInterfaceHundredGigabitEthernet = types.StringValue(value.String()) } + if value := res.Get(prefix + "ip.ssh.bulk-mode"); value.Exists() { + data.IpSshBulkMode = types.BoolValue(true) + } else { + data.IpSshBulkMode = types.BoolValue(false) + } + if value := res.Get(prefix + "ip.ssh.bulk-mode.window-size"); value.Exists() { + data.IpSshBulkModeWindowSize = types.Int64Value(value.Int()) + } if value := res.Get(prefix + "control-plane.Cisco-IOS-XE-policy:service-policy.input"); value.Exists() { data.ControlPlaneServicePolicyInput = types.StringValue(value.String()) } @@ -3763,6 +3805,12 @@ func (data *System) getDeletedItems(ctx context.Context, state System) []string if !state.ControlPlaneServicePolicyInput.IsNull() && data.ControlPlaneServicePolicyInput.IsNull() { deletedItems = append(deletedItems, fmt.Sprintf("%v/control-plane/Cisco-IOS-XE-policy:service-policy/input", state.getPath())) } + if !state.IpSshBulkModeWindowSize.IsNull() && data.IpSshBulkModeWindowSize.IsNull() { + deletedItems = append(deletedItems, fmt.Sprintf("%v/ip/ssh/bulk-mode/window-size", state.getPath())) + } + if !state.IpSshBulkMode.IsNull() && data.IpSshBulkMode.IsNull() { + deletedItems = append(deletedItems, fmt.Sprintf("%v/ip/ssh/bulk-mode", state.getPath())) + } if !state.IpSshSourceInterfaceHundredGigabitEthernet.IsNull() && data.IpSshSourceInterfaceHundredGigabitEthernet.IsNull() { deletedItems = append(deletedItems, fmt.Sprintf("%v/ip/ssh/source-interface-config/HundredGigE", state.getPath())) } @@ -4169,6 +4217,9 @@ func (data *System) getEmptyLeafsDelete(ctx context.Context) []string { emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/subscriber/templating", data.getPath())) } + if !data.IpSshBulkMode.IsNull() && !data.IpSshBulkMode.ValueBool() { + emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/ip/ssh/bulk-mode", data.getPath())) + } if !data.IpScpServerEnable.IsNull() && !data.IpScpServerEnable.ValueBool() { emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/ip/scp/server/enable", data.getPath())) } @@ -4435,6 +4486,12 @@ func (data *System) getDeletePaths(ctx context.Context) []string { if !data.ControlPlaneServicePolicyInput.IsNull() { deletePaths = append(deletePaths, fmt.Sprintf("%v/control-plane/Cisco-IOS-XE-policy:service-policy/input", data.getPath())) } + if !data.IpSshBulkModeWindowSize.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/ip/ssh/bulk-mode/window-size", data.getPath())) + } + if !data.IpSshBulkMode.IsNull() { + deletePaths = append(deletePaths, fmt.Sprintf("%v/ip/ssh/bulk-mode", data.getPath())) + } if !data.IpSshSourceInterfaceHundredGigabitEthernet.IsNull() { deletePaths = append(deletePaths, fmt.Sprintf("%v/ip/ssh/source-interface-config/HundredGigE", data.getPath())) } diff --git a/internal/provider/resource_iosxe_system.go b/internal/provider/resource_iosxe_system.go index ffdb5db1a..a9c52b6b0 100644 --- a/internal/provider/resource_iosxe_system.go +++ b/internal/provider/resource_iosxe_system.go @@ -540,6 +540,17 @@ func (r *SystemResource) Schema(ctx context.Context, req resource.SchemaRequest, MarkdownDescription: helpers.NewAttributeDescription("Hundred GigabitEthernet").String, Optional: true, }, + "ip_ssh_bulk_mode": schema.BoolAttribute{ + MarkdownDescription: helpers.NewAttributeDescription("Enable optimizations for bulk data transfer procedures").String, + Optional: true, + }, + "ip_ssh_bulk_mode_window_size": schema.Int64Attribute{ + MarkdownDescription: helpers.NewAttributeDescription("Window-size value").AddIntegerRangeDescription(131072, 1073741824).String, + Optional: true, + Validators: []validator.Int64{ + int64validator.Between(131072, 1073741824), + }, + }, "control_plane_service_policy_input": schema.StringAttribute{ MarkdownDescription: helpers.NewAttributeDescription("Assign policy-map to the input of an interface").String, Optional: true, diff --git a/internal/provider/resource_iosxe_system_test.go b/internal/provider/resource_iosxe_system_test.go index 10a76503e..3916269f7 100644 --- a/internal/provider/resource_iosxe_system_test.go +++ b/internal/provider/resource_iosxe_system_test.go @@ -73,6 +73,8 @@ func TestAccIosxeSystem(t *testing.T) { } checks = append(checks, resource.TestCheckResourceAttr("iosxe_system.test", "ip_ssh_time_out", "120")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_system.test", "ip_ssh_authentication_retries", "3")) + checks = append(checks, resource.TestCheckResourceAttr("iosxe_system.test", "ip_ssh_bulk_mode", "true")) + checks = append(checks, resource.TestCheckResourceAttr("iosxe_system.test", "ip_ssh_bulk_mode_window_size", "262144")) if os.Getenv("IOSXE1715") != "" { checks = append(checks, resource.TestCheckResourceAttr("iosxe_system.test", "ip_hosts.0.name", "test.router.com")) checks = append(checks, resource.TestCheckResourceAttr("iosxe_system.test", "ip_hosts.0.ips.0", "3.3.3.3")) @@ -194,6 +196,8 @@ func testAccIosxeSystemConfig_all() string { } config += ` ip_ssh_time_out = 120` + "\n" config += ` ip_ssh_authentication_retries = 3` + "\n" + config += ` ip_ssh_bulk_mode = true` + "\n" + config += ` ip_ssh_bulk_mode_window_size = 262144` + "\n" if os.Getenv("IOSXE1715") != "" { config += ` ip_hosts = [{` + "\n" config += ` name = "test.router.com"` + "\n" diff --git a/templates/guides/changelog.md.tmpl b/templates/guides/changelog.md.tmpl index 9b08bc539..b16c51b92 100644 --- a/templates/guides/changelog.md.tmpl +++ b/templates/guides/changelog.md.tmpl @@ -13,6 +13,7 @@ description: |- - Add `ip_domain_lookup_nsap`, `ip_domain_lookup_recursive`, and `ip_domain_lookup_vrfs*` attributes to `iosxe_system` resource and data source - Add `iosxe_evpn_ethernet_segment` resource and data source for managing L2VPN EVPN Ethernet Segment configuration - Add `evpn_ethernet_segments` attribute to `iosxe_interface_ethernet` and `iosxe_interface_port_channel` resources and data sources +- Add `ip_ssh_bulk_mode` and `ip_ssh_bulk_mode_window_size` attributes to `iosxe_system` resource and data source ## 0.9.3 From 2962acc0e635840247acf9661030f7644c7d8b21 Mon Sep 17 00:00:00 2001 From: Cameron Schaeffer Date: Fri, 31 Oct 2025 15:16:49 +0000 Subject: [PATCH 2/3] fix: ensure SSH bulk-mode window-size is set correctly When bulk-mode is enabled with a custom window-size, both values are now set in a single operation. This ensures the presence container includes the window-size value rather than defaulting to 131072. Fixes issue where bulk-mode would enable but use default window-size instead of the configured custom value. --- internal/provider/model_iosxe_system.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/internal/provider/model_iosxe_system.go b/internal/provider/model_iosxe_system.go index a2341293e..c9ceb5b34 100644 --- a/internal/provider/model_iosxe_system.go +++ b/internal/provider/model_iosxe_system.go @@ -655,10 +655,15 @@ func (data System) toBody(ctx context.Context) string { } if !data.IpSshBulkMode.IsNull() && !data.IpSshBulkMode.IsUnknown() { if data.IpSshBulkMode.ValueBool() { - body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ip.ssh.bulk-mode", map[string]string{}) + // For presence container, include window-size in the same operation if set + if !data.IpSshBulkModeWindowSize.IsNull() && !data.IpSshBulkModeWindowSize.IsUnknown() { + body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ip.ssh.bulk-mode.window-size", strconv.FormatInt(data.IpSshBulkModeWindowSize.ValueInt64(), 10)) + } else { + body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ip.ssh.bulk-mode", map[string]string{}) + } } - } - if !data.IpSshBulkModeWindowSize.IsNull() && !data.IpSshBulkModeWindowSize.IsUnknown() { + } else if !data.IpSshBulkModeWindowSize.IsNull() && !data.IpSshBulkModeWindowSize.IsUnknown() { + // If only window-size is set, setting it will implicitly enable bulk-mode body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ip.ssh.bulk-mode.window-size", strconv.FormatInt(data.IpSshBulkModeWindowSize.ValueInt64(), 10)) } if !data.ControlPlaneServicePolicyInput.IsNull() && !data.ControlPlaneServicePolicyInput.IsUnknown() { From b31e424331244b12d1beb40314db4e539c25852f Mon Sep 17 00:00:00 2001 From: Cameron Schaeffer Date: Fri, 31 Oct 2025 16:42:33 +0000 Subject: [PATCH 3/3] fix: remove manual edits from generated code to match CI/CD expectations The generator's simple approach for SSH bulk-mode works correctly - setting child values on presence containers automatically creates the parent container. Manual edits to generated files caused CI/CD failure as the generator regenerates all code from templates during the build process. This commit removes the manual 'atomic' logic and trusts the generator, ensuring CI/CD validation passes. --- internal/provider/model_iosxe_system.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/internal/provider/model_iosxe_system.go b/internal/provider/model_iosxe_system.go index c9ceb5b34..a2341293e 100644 --- a/internal/provider/model_iosxe_system.go +++ b/internal/provider/model_iosxe_system.go @@ -655,15 +655,10 @@ func (data System) toBody(ctx context.Context) string { } if !data.IpSshBulkMode.IsNull() && !data.IpSshBulkMode.IsUnknown() { if data.IpSshBulkMode.ValueBool() { - // For presence container, include window-size in the same operation if set - if !data.IpSshBulkModeWindowSize.IsNull() && !data.IpSshBulkModeWindowSize.IsUnknown() { - body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ip.ssh.bulk-mode.window-size", strconv.FormatInt(data.IpSshBulkModeWindowSize.ValueInt64(), 10)) - } else { - body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ip.ssh.bulk-mode", map[string]string{}) - } + body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ip.ssh.bulk-mode", map[string]string{}) } - } else if !data.IpSshBulkModeWindowSize.IsNull() && !data.IpSshBulkModeWindowSize.IsUnknown() { - // If only window-size is set, setting it will implicitly enable bulk-mode + } + if !data.IpSshBulkModeWindowSize.IsNull() && !data.IpSshBulkModeWindowSize.IsUnknown() { body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"ip.ssh.bulk-mode.window-size", strconv.FormatInt(data.IpSshBulkModeWindowSize.ValueInt64(), 10)) } if !data.ControlPlaneServicePolicyInput.IsNull() && !data.ControlPlaneServicePolicyInput.IsUnknown() {