From 536768d5c3d324da04ee42f28270d1a15f19ccee Mon Sep 17 00:00:00 2001 From: kuba-mazurkiewicz Date: Mon, 2 Dec 2024 10:57:56 +0100 Subject: [PATCH] Add device unreachability warning to anycast_gateway, fabric_l2_handoff, fabric_device, fabric_port_assignment and provision_device resources --- CHANGELOG.md | 1 + docs/guides/changelog.md | 1 + gen/definitions/anycast_gateway.yaml | 1 + gen/definitions/fabric_device.yaml | 1 + gen/definitions/fabric_l2_handoff.yaml | 1 + .../fabric_l3_handoff_ip_transit.yaml | 1 + gen/definitions/fabric_port_assignment.yaml | 1 + gen/definitions/fabric_provision_device.yaml | 1 + gen/generator.go | 85 ++++++++++--------- gen/schema/schema.yaml | 1 + gen/templates/resource.go | 12 +++ ...resource_catalystcenter_anycast_gateway.go | 11 ++- .../resource_catalystcenter_fabric_device.go | 11 ++- ...source_catalystcenter_fabric_l2_handoff.go | 11 ++- ...lystcenter_fabric_l3_handoff_ip_transit.go | 3 + ...e_catalystcenter_fabric_port_assignment.go | 11 ++- ..._catalystcenter_fabric_provision_device.go | 11 ++- templates/guides/changelog.md.tmpl | 1 + 18 files changed, 113 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a40c68b..4dca495 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## 0.1.17 (unreleased) +- Add device unreachability warning to `catalystcenter_anycast_gateway`, `catalystcenter_fabric_l2_handoff`, `catalystcenter_fabric_device`, `catalystcenter_fabric_port_assignment` and `catalystcenter_provision_device` resources - Add `isAuthKeyPSK` and `isAuthKeyPSKPlusFT` attributes to `catalystcenter_wireless_ssid` resource ## 0.1.16 diff --git a/docs/guides/changelog.md b/docs/guides/changelog.md index 5931b27..6a951a9 100644 --- a/docs/guides/changelog.md +++ b/docs/guides/changelog.md @@ -9,6 +9,7 @@ description: |- ## 0.1.17 (unreleased) +- Add device unreachability warning to `catalystcenter_anycast_gateway`, `catalystcenter_fabric_l2_handoff`, `catalystcenter_fabric_device`, `catalystcenter_fabric_port_assignment` and `catalystcenter_provision_device` resources - Add `isAuthKeyPSK` and `isAuthKeyPSKPlusFT` attributes to `catalystcenter_wireless_ssid` resource ## 0.1.16 diff --git a/gen/definitions/anycast_gateway.yaml b/gen/definitions/anycast_gateway.yaml index c5a4bf1..f950df2 100644 --- a/gen/definitions/anycast_gateway.yaml +++ b/gen/definitions/anycast_gateway.yaml @@ -9,6 +9,7 @@ data_source_no_id: true skip_minimum_test: true put_id_include_path: "0.id" put_no_id: true +device_unreachability_warning: true doc_category: SDA attributes: - model_name: fabricId diff --git a/gen/definitions/fabric_device.yaml b/gen/definitions/fabric_device.yaml index 6d1ca9f..00e8f64 100644 --- a/gen/definitions/fabric_device.yaml +++ b/gen/definitions/fabric_device.yaml @@ -8,6 +8,7 @@ put_id_include_path: 0.id import_no_id: true data_source_no_id: true put_no_id: true +device_unreachability_warning: true doc_category: SDA test_tags: [SDA] attributes: diff --git a/gen/definitions/fabric_l2_handoff.yaml b/gen/definitions/fabric_l2_handoff.yaml index 5434832..b34defe 100644 --- a/gen/definitions/fabric_l2_handoff.yaml +++ b/gen/definitions/fabric_l2_handoff.yaml @@ -7,6 +7,7 @@ id_from_query_path_attribute: id put_id_include_path: 0.id get_from_all: true put_no_id: true +device_unreachability_warning: true doc_category: SDA test_tags: [SDA] attributes: diff --git a/gen/definitions/fabric_l3_handoff_ip_transit.yaml b/gen/definitions/fabric_l3_handoff_ip_transit.yaml index af404cd..8a8a4b0 100644 --- a/gen/definitions/fabric_l3_handoff_ip_transit.yaml +++ b/gen/definitions/fabric_l3_handoff_ip_transit.yaml @@ -7,6 +7,7 @@ id_from_query_path_attribute: id put_id_include_path: 0.id get_from_all: true put_no_id: true +device_unreachability_warning: true doc_category: SDA test_tags: [SDA] attributes: diff --git a/gen/definitions/fabric_port_assignment.yaml b/gen/definitions/fabric_port_assignment.yaml index e7104fc..ba86909 100644 --- a/gen/definitions/fabric_port_assignment.yaml +++ b/gen/definitions/fabric_port_assignment.yaml @@ -8,6 +8,7 @@ data_source_no_id: true id_from_attribute: true root_list: true skip_minimum_test: true +device_unreachability_warning: true doc_category: SDA test_tags: [SDA] attributes: diff --git a/gen/definitions/fabric_provision_device.yaml b/gen/definitions/fabric_provision_device.yaml index a5065a1..2f74821 100644 --- a/gen/definitions/fabric_provision_device.yaml +++ b/gen/definitions/fabric_provision_device.yaml @@ -7,6 +7,7 @@ import_no_id: true data_source_no_id: true put_id_include_path: "0.id" put_no_id: true +device_unreachability_warning: true doc_category: SDA test_tags: [SDA] attributes: diff --git a/gen/generator.go b/gen/generator.go index 761bc40..9485ad3 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -94,48 +94,49 @@ var templates = []t{ } type YamlConfig struct { - Name string `yaml:"name"` - NoResource bool `yaml:"no_resource"` - NoDataSource bool `yaml:"no_data_source"` - RestEndpoint string `yaml:"rest_endpoint"` - GetRestEndpoint string `yaml:"get_rest_endpoint"` - PutRestEndpoint string `yaml:"put_rest_endpoint"` - DeleteRestEndpoint string `yaml:"delete_rest_endpoint"` - GetNoId bool `yaml:"get_no_id"` - GetFromAll bool `yaml:"get_from_all"` - GetRequiresId bool `yaml:"get_requires_id"` - GetExtraQueryParams string `yaml:"get_extra_query_params"` - NoDelete bool `yaml:"no_delete"` - DataSourceNoId bool `yaml:"data_source_no_id"` - DeleteNoId bool `yaml:"delete_no_id"` - NoUpdate bool `yaml:"no_update"` - NoRead bool `yaml:"no_read"` - NoImport bool `yaml:"no_import"` - ImportNoId bool `yaml:"import_no_id"` - PostUpdate bool `yaml:"post_update"` - PutCreate bool `yaml:"put_create"` - RootList bool `yaml:"root_list"` - NoReadPrefix bool `yaml:"no_read_prefix"` - IdPath string `yaml:"id_path"` - IdFromQueryPath string `yaml:"id_from_query_path"` - IdFromQueryPathAttribute string `yaml:"id_from_query_path_attribute"` - IdQueryParam string `yaml:"id_query_param"` - IdFromAttribute bool `yaml:"id_from_attribute"` - PutIdIncludePath string `yaml:"put_id_include_path"` - PutIdQueryParam string `yaml:"put_id_query_param"` - PutNoId bool `yaml:"put_no_id"` - PutUpdateId bool `yaml:"put_update_id"` - DeleteIdQueryParam string `yaml:"delete_id_query_param"` - MinimumVersion string `yaml:"minimum_version"` - DsDescription string `yaml:"ds_description"` - ResDescription string `yaml:"res_description"` - DocCategory string `yaml:"doc_category"` - ExcludeTest bool `yaml:"exclude_test"` - SkipMinimumTest bool `yaml:"skip_minimum_test"` - Attributes []YamlConfigAttribute `yaml:"attributes"` - TestTags []string `yaml:"test_tags"` - TestPrerequisites string `yaml:"test_prerequisites"` - MaxAsyncWaitTime int64 `yaml:"max_async_wait_time"` + Name string `yaml:"name"` + NoResource bool `yaml:"no_resource"` + NoDataSource bool `yaml:"no_data_source"` + RestEndpoint string `yaml:"rest_endpoint"` + GetRestEndpoint string `yaml:"get_rest_endpoint"` + PutRestEndpoint string `yaml:"put_rest_endpoint"` + DeleteRestEndpoint string `yaml:"delete_rest_endpoint"` + GetNoId bool `yaml:"get_no_id"` + GetFromAll bool `yaml:"get_from_all"` + GetRequiresId bool `yaml:"get_requires_id"` + GetExtraQueryParams string `yaml:"get_extra_query_params"` + NoDelete bool `yaml:"no_delete"` + DataSourceNoId bool `yaml:"data_source_no_id"` + DeleteNoId bool `yaml:"delete_no_id"` + NoUpdate bool `yaml:"no_update"` + NoRead bool `yaml:"no_read"` + NoImport bool `yaml:"no_import"` + ImportNoId bool `yaml:"import_no_id"` + PostUpdate bool `yaml:"post_update"` + PutCreate bool `yaml:"put_create"` + RootList bool `yaml:"root_list"` + NoReadPrefix bool `yaml:"no_read_prefix"` + IdPath string `yaml:"id_path"` + IdFromQueryPath string `yaml:"id_from_query_path"` + IdFromQueryPathAttribute string `yaml:"id_from_query_path_attribute"` + IdQueryParam string `yaml:"id_query_param"` + IdFromAttribute bool `yaml:"id_from_attribute"` + DeviceUnreachabilityWarning bool `yaml:"device_unreachability_warning"` + PutIdIncludePath string `yaml:"put_id_include_path"` + PutIdQueryParam string `yaml:"put_id_query_param"` + PutNoId bool `yaml:"put_no_id"` + PutUpdateId bool `yaml:"put_update_id"` + DeleteIdQueryParam string `yaml:"delete_id_query_param"` + MinimumVersion string `yaml:"minimum_version"` + DsDescription string `yaml:"ds_description"` + ResDescription string `yaml:"res_description"` + DocCategory string `yaml:"doc_category"` + ExcludeTest bool `yaml:"exclude_test"` + SkipMinimumTest bool `yaml:"skip_minimum_test"` + Attributes []YamlConfigAttribute `yaml:"attributes"` + TestTags []string `yaml:"test_tags"` + TestPrerequisites string `yaml:"test_prerequisites"` + MaxAsyncWaitTime int64 `yaml:"max_async_wait_time"` } type YamlConfigAttribute struct { diff --git a/gen/schema/schema.yaml b/gen/schema/schema.yaml index f84433b..e6bc6de 100644 --- a/gen/schema/schema.yaml +++ b/gen/schema/schema.yaml @@ -26,6 +26,7 @@ id_from_query_path: str(required=False) # Specify path to ID container if ID is id_from_query_path_attribute: str(required=False) # Specify attribute name of ID, only relevant if "id_from_query_path" option used, default is "id" id_query_param: str(required=False) # Query parameter used to specify the ID id_from_attribute: bool(required=False) # Set to true if the ID is derived from an attribute +device_unreachability_warning: bool(required=False) # Set to true if a warning should be displayed for device unreachability instead of error put_id_include_path: str(required=False) # If PUT needs to have specific JSON path where ID should be inserted put_id_query_param: str(required=False) # If PUT needs to have specific query parameter where ID should be inserted put_no_id: bool(required=False) # Set to true if the PUT request does not require an ID diff --git a/gen/templates/resource.go b/gen/templates/resource.go index 980b4ae..3cf36e4 100644 --- a/gen/templates/resource.go +++ b/gen/templates/resource.go @@ -455,8 +455,20 @@ func (r *{{camelCase .Name}}Resource) Create(ctx context.Context, req resource.C res, err := r.client.Post(plan.getPath() + params, body {{- if .MaxAsyncWaitTime }}, func(r *cc.Req) { r.MaxAsyncWaitTime={{.MaxAsyncWaitTime}} }{{end}}) {{- end}} if err != nil { + {{- if .DeviceUnreachabilityWarning}} + errorCode := res.Get("response.errorCode").String() + if errorCode == "NCDP10000" { + // Log a warning and continue execution when device is unreachable + failureReason := res.Get("response.failureReason").String() + resp.Diagnostics.AddWarning("Device Unreachability Warning", fmt.Sprintf("Device unreachability detected (error code: %s, reason %s).", errorCode, failureReason)) + } else { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (%s), got error: %s, %s", "POST", err, res.String())) + return + } + {{- else}} resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (%s), got error: %s, %s", {{- if .PutCreate }} "PUT" {{- else }} "POST" {{- end }}, err, res.String())) return + {{- end}} } {{- /* Check if id can be resolved directly from response */}} {{- if .IdPath}} diff --git a/internal/provider/resource_catalystcenter_anycast_gateway.go b/internal/provider/resource_catalystcenter_anycast_gateway.go index 5f3a891..699c706 100644 --- a/internal/provider/resource_catalystcenter_anycast_gateway.go +++ b/internal/provider/resource_catalystcenter_anycast_gateway.go @@ -204,8 +204,15 @@ func (r *AnycastGatewayResource) Create(ctx context.Context, req resource.Create params := "" res, err := r.client.Post(plan.getPath()+params, body) if err != nil { - resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (%s), got error: %s, %s", "POST", err, res.String())) - return + errorCode := res.Get("response.errorCode").String() + if errorCode == "NCDP10000" { + // Log a warning and continue execution when device is unreachable + failureReason := res.Get("response.failureReason").String() + resp.Diagnostics.AddWarning("Device Unreachability Warning", fmt.Sprintf("Device unreachability detected (error code: %s, reason %s).", errorCode, failureReason)) + } else { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (%s), got error: %s, %s", "POST", err, res.String())) + return + } } params = "" params += "?fabricId=" + url.QueryEscape(plan.FabricId.ValueString()) + "&virtualNetworkName=" + url.QueryEscape(plan.VirtualNetworkName.ValueString()) + "&ipPoolName=" + url.QueryEscape(plan.IpPoolName.ValueString()) diff --git a/internal/provider/resource_catalystcenter_fabric_device.go b/internal/provider/resource_catalystcenter_fabric_device.go index b0f8fcf..8d4234f 100644 --- a/internal/provider/resource_catalystcenter_fabric_device.go +++ b/internal/provider/resource_catalystcenter_fabric_device.go @@ -157,8 +157,15 @@ func (r *FabricDeviceResource) Create(ctx context.Context, req resource.CreateRe params := "" res, err := r.client.Post(plan.getPath()+params, body) if err != nil { - resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (%s), got error: %s, %s", "POST", err, res.String())) - return + errorCode := res.Get("response.errorCode").String() + if errorCode == "NCDP10000" { + // Log a warning and continue execution when device is unreachable + failureReason := res.Get("response.failureReason").String() + resp.Diagnostics.AddWarning("Device Unreachability Warning", fmt.Sprintf("Device unreachability detected (error code: %s, reason %s).", errorCode, failureReason)) + } else { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (%s), got error: %s, %s", "POST", err, res.String())) + return + } } params = "" params += "?networkDeviceId=" + url.QueryEscape(plan.NetworkDeviceId.ValueString()) + "&fabricId=" + url.QueryEscape(plan.FabricId.ValueString()) diff --git a/internal/provider/resource_catalystcenter_fabric_l2_handoff.go b/internal/provider/resource_catalystcenter_fabric_l2_handoff.go index c76dac9..a8e22f5 100644 --- a/internal/provider/resource_catalystcenter_fabric_l2_handoff.go +++ b/internal/provider/resource_catalystcenter_fabric_l2_handoff.go @@ -138,8 +138,15 @@ func (r *FabricL2HandoffResource) Create(ctx context.Context, req resource.Creat params := "" res, err := r.client.Post(plan.getPath()+params, body) if err != nil { - resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (%s), got error: %s, %s", "POST", err, res.String())) - return + errorCode := res.Get("response.errorCode").String() + if errorCode == "NCDP10000" { + // Log a warning and continue execution when device is unreachable + failureReason := res.Get("response.failureReason").String() + resp.Diagnostics.AddWarning("Device Unreachability Warning", fmt.Sprintf("Device unreachability detected (error code: %s, reason %s).", errorCode, failureReason)) + } else { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (%s), got error: %s, %s", "POST", err, res.String())) + return + } } params = "" params += "?networkDeviceId=" + url.QueryEscape(plan.NetworkDeviceId.ValueString()) + "&fabricId=" + url.QueryEscape(plan.FabricId.ValueString()) diff --git a/internal/provider/resource_catalystcenter_fabric_l3_handoff_ip_transit.go b/internal/provider/resource_catalystcenter_fabric_l3_handoff_ip_transit.go index 815835c..51ce26f 100644 --- a/internal/provider/resource_catalystcenter_fabric_l3_handoff_ip_transit.go +++ b/internal/provider/resource_catalystcenter_fabric_l3_handoff_ip_transit.go @@ -170,6 +170,7 @@ func (r *FabricL3HandoffIPTransitResource) Configure(_ context.Context, req reso // End of section. //template:end model +// Section below is generated&owned by "gen/generator.go". //template:begin create func (r *FabricL3HandoffIPTransitResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { var plan FabricL3HandoffIPTransit @@ -213,6 +214,8 @@ func (r *FabricL3HandoffIPTransitResource) Create(ctx context.Context, req resou resp.Diagnostics.Append(diags...) } +// End of section. //template:end create + // Section below is generated&owned by "gen/generator.go". //template:begin read func (r *FabricL3HandoffIPTransitResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { var state FabricL3HandoffIPTransit diff --git a/internal/provider/resource_catalystcenter_fabric_port_assignment.go b/internal/provider/resource_catalystcenter_fabric_port_assignment.go index fbdbdae..d46df82 100644 --- a/internal/provider/resource_catalystcenter_fabric_port_assignment.go +++ b/internal/provider/resource_catalystcenter_fabric_port_assignment.go @@ -162,8 +162,15 @@ func (r *FabricPortAssignmentResource) Create(ctx context.Context, req resource. params := "" res, err := r.client.Post(plan.getPath()+params, body) if err != nil { - resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (%s), got error: %s, %s", "POST", err, res.String())) - return + errorCode := res.Get("response.errorCode").String() + if errorCode == "NCDP10000" { + // Log a warning and continue execution when device is unreachable + failureReason := res.Get("response.failureReason").String() + resp.Diagnostics.AddWarning("Device Unreachability Warning", fmt.Sprintf("Device unreachability detected (error code: %s, reason %s).", errorCode, failureReason)) + } else { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (%s), got error: %s, %s", "POST", err, res.String())) + return + } } plan.Id = types.StringValue(fmt.Sprint(plan.NetworkDeviceId.ValueString())) diff --git a/internal/provider/resource_catalystcenter_fabric_provision_device.go b/internal/provider/resource_catalystcenter_fabric_provision_device.go index 3ad646b..a15e739 100644 --- a/internal/provider/resource_catalystcenter_fabric_provision_device.go +++ b/internal/provider/resource_catalystcenter_fabric_provision_device.go @@ -115,8 +115,15 @@ func (r *FabricProvisionDeviceResource) Create(ctx context.Context, req resource params := "" res, err := r.client.Post(plan.getPath()+params, body) if err != nil { - resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (%s), got error: %s, %s", "POST", err, res.String())) - return + errorCode := res.Get("response.errorCode").String() + if errorCode == "NCDP10000" { + // Log a warning and continue execution when device is unreachable + failureReason := res.Get("response.failureReason").String() + resp.Diagnostics.AddWarning("Device Unreachability Warning", fmt.Sprintf("Device unreachability detected (error code: %s, reason %s).", errorCode, failureReason)) + } else { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (%s), got error: %s, %s", "POST", err, res.String())) + return + } } params = "" params += "?siteId=" + url.QueryEscape(plan.SiteId.ValueString()) + "&networkDeviceId=" + url.QueryEscape(plan.NetworkDeviceId.ValueString()) diff --git a/templates/guides/changelog.md.tmpl b/templates/guides/changelog.md.tmpl index 5931b27..6a951a9 100644 --- a/templates/guides/changelog.md.tmpl +++ b/templates/guides/changelog.md.tmpl @@ -9,6 +9,7 @@ description: |- ## 0.1.17 (unreleased) +- Add device unreachability warning to `catalystcenter_anycast_gateway`, `catalystcenter_fabric_l2_handoff`, `catalystcenter_fabric_device`, `catalystcenter_fabric_port_assignment` and `catalystcenter_provision_device` resources - Add `isAuthKeyPSK` and `isAuthKeyPSKPlusFT` attributes to `catalystcenter_wireless_ssid` resource ## 0.1.16