From 7ccfae22c98ccce7e84683fc7174feedfcd5da47 Mon Sep 17 00:00:00 2001 From: danischm Date: Tue, 25 Jul 2023 13:31:54 +0200 Subject: [PATCH] Refactor cli device template resource and data source --- docs/data-sources/cli_device_template.md | 9 +-- docs/resources/cli_device_template.md | 18 +++--- .../sdwan_cli_device_template/resource.tf | 11 ++-- .../generic/cli_device_template.yaml | 46 ++++++++++++++ gen/doc_category.go | 1 - gen/generator.go | 1 + gen/schema/schema.yaml | 1 + gen/templates/generic/resource.go | 2 +- gen/templates/provider.go | 2 - .../data_source_sdwan_cli_device_template.go | 19 +++--- ...a_source_sdwan_cli_device_template_test.go | 15 +++-- .../model_sdwan_cli_device_template.go | 63 ++++++++++++++----- internal/provider/provider.go | 4 +- .../resource_sdwan_cli_device_template.go | 58 ++++++++++++----- ...resource_sdwan_cli_device_template_test.go | 30 ++++----- 15 files changed, 196 insertions(+), 84 deletions(-) create mode 100644 gen/definitions/generic/cli_device_template.yaml diff --git a/docs/data-sources/cli_device_template.md b/docs/data-sources/cli_device_template.md index b547b858..8989bf84 100644 --- a/docs/data-sources/cli_device_template.md +++ b/docs/data-sources/cli_device_template.md @@ -3,12 +3,12 @@ page_title: "sdwan_cli_device_template Data Source - terraform-provider-sdwan" subcategory: "Device Templates" description: |- - This data source can read a CLI device template. + This data source can read the CLI Device Template . --- # sdwan_cli_device_template (Data Source) -This data source can read a CLI device template. +This data source can read the CLI Device Template . ## Example Usage @@ -23,12 +23,13 @@ data "sdwan_cli_device_template" "example" { ### Required -- `id` (String) The id of the deivce template +- `id` (String) The id of the object ### Read-Only - `cli_configuration` (String) CLI configuration - `cli_type` (String) CLI type -- `description` (String) The description of the feature template +- `description` (String) The description of the device template - `device_type` (String) The device type (e.g., `vedge-ISR-4331`) - `name` (String) The name of the device template +- `version` (Number) The version of the object diff --git a/docs/resources/cli_device_template.md b/docs/resources/cli_device_template.md index 3976005a..064709a9 100644 --- a/docs/resources/cli_device_template.md +++ b/docs/resources/cli_device_template.md @@ -3,25 +3,22 @@ page_title: "sdwan_cli_device_template Resource - terraform-provider-sdwan" subcategory: "Device Templates" description: |- - This resource can manage a CLI device template. + This resource can manage a CLI Device Template . --- # sdwan_cli_device_template (Resource) -This resource can manage a CLI device template. +This resource can manage a CLI Device Template . ## Example Usage ```terraform -resource "sdwan_cli_device_template" "test" { - name = "cli_template_1" - description = "Terraform integration test" +resource "sdwan_cli_device_template" "example" { + name = "Example" + description = "My description" device_type = "vedge-ISR-4331" cli_type = "device" - cli_configuration = <<-EOT - system - host-name {{test}}-ISR4331-1200-1 - EOT + cli_configuration = " system\n host-name R1-ISR4331-1200-1" } ``` @@ -39,7 +36,8 @@ resource "sdwan_cli_device_template" "test" { ### Read-Only -- `id` (String) The id of the device template +- `id` (String) The id of the object +- `version` (Number) The version of the object ## Import diff --git a/examples/resources/sdwan_cli_device_template/resource.tf b/examples/resources/sdwan_cli_device_template/resource.tf index 766370cc..734d412e 100644 --- a/examples/resources/sdwan_cli_device_template/resource.tf +++ b/examples/resources/sdwan_cli_device_template/resource.tf @@ -1,10 +1,7 @@ -resource "sdwan_cli_device_template" "test" { - name = "cli_template_1" - description = "Terraform integration test" +resource "sdwan_cli_device_template" "example" { + name = "Example" + description = "My description" device_type = "vedge-ISR-4331" cli_type = "device" - cli_configuration = <<-EOT - system - host-name {{test}}-ISR4331-1200-1 - EOT + cli_configuration = " system\n host-name R1-ISR4331-1200-1" } diff --git a/gen/definitions/generic/cli_device_template.yaml b/gen/definitions/generic/cli_device_template.yaml new file mode 100644 index 00000000..f447383c --- /dev/null +++ b/gen/definitions/generic/cli_device_template.yaml @@ -0,0 +1,46 @@ +--- +name: CLI Device Template +rest_endpoint: /template/device/ +get_rest_endpoint: /template/device/object/ +post_rest_endpoint: /template/device/cli/ +has_version: true +id_attribute: templateId +doc_category: Device Templates +attributes: + - model_name: configType + type: String + value: file + - model_name: factoryDefault + Type: Bool + value: false + - model_name: templateName + tf_name: name + type: String + mandatory: true + description: The name of the device template + example: Example + - model_name: templateDescription + tf_name: description + type: String + mandatory: true + description: The description of the device template + example: My description + - model_name: deviceType + tf_name: device_type + type: String + mandatory: true + description: The device type (e.g., `vedge-ISR-4331`) + example: vedge-ISR-4331 + - model_name: cliType + tf_name: cli_type + type: String + mandatory: true + enum_values: [device, intend] + description: CLI type + example: device + - model_name: templateConfiguration + tf_name: cli_configuration + type: String + mandatory: true + description: CLI configuration + example: " system\\n host-name R1-ISR4331-1200-1" diff --git a/gen/doc_category.go b/gen/doc_category.go index 0ce1bf25..88ddbf9a 100644 --- a/gen/doc_category.go +++ b/gen/doc_category.go @@ -41,7 +41,6 @@ type YamlConfig struct { var docPaths = []string{"./docs/data-sources/", "./docs/resources/"} var extraDocs = map[string]string{ - "cli_device_template": "Device Templates", "feature_device_template": "Device Templates", "attach_feature_device_template": "Device Templates", } diff --git a/gen/generator.go b/gen/generator.go index 8ab0dd8d..387fdb24 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -143,6 +143,7 @@ type YamlConfig struct { Model string `yaml:"model"` RestEndpoint string `yaml:"rest_endpoint"` GetRestEndpoint string `yaml:"get_rest_endpoint"` + PostRestEndpoint string `yaml:"post_rest_endpoint"` Type string `yaml:"type"` MinimumVersion string `yaml:"minimum_version"` DsDescription string `yaml:"ds_description"` diff --git a/gen/schema/schema.yaml b/gen/schema/schema.yaml index 20143e9d..4c65f47d 100644 --- a/gen/schema/schema.yaml +++ b/gen/schema/schema.yaml @@ -3,6 +3,7 @@ name: str() model: str(required=False) rest_endpoint: str(required=False) get_rest_endpoint: str(required=False) +post_rest_endpoint: str(required=False) type: str(required=False) minimum_version: str() ds_description: str(required=False) diff --git a/gen/templates/generic/resource.go b/gen/templates/generic/resource.go index 722006c3..e0043586 100644 --- a/gen/templates/generic/resource.go +++ b/gen/templates/generic/resource.go @@ -395,7 +395,7 @@ func (r *{{camelCase .Name}}Resource) Create(ctx context.Context, req resource.C // Create object body := plan.toBody(ctx) - res, err := r.client.Post("{{.RestEndpoint}}", body) + res, err := r.client.Post("{{if .PostRestEndpoint}}{{.PostRestEndpoint}}{{else}}{{.RestEndpoint}}{{end}}", body) if err != nil { resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (POST), got error: %s, %s", err, res.String())) return diff --git a/gen/templates/provider.go b/gen/templates/provider.go index 1094ad4b..2287025c 100644 --- a/gen/templates/provider.go +++ b/gen/templates/provider.go @@ -248,7 +248,6 @@ func (p *SdwanProvider) Resources(ctx context.Context) []func() resource.Resourc {{- range .Generic}} New{{camelCase .}}Resource, {{- end}} - NewCLIDeviceTemplateResource, NewFeatureDeviceTemplateResource, NewAttachFeatureDeviceTemplateResource, } @@ -262,7 +261,6 @@ func (p *SdwanProvider) DataSources(ctx context.Context) []func() datasource.Dat {{- range .Generic}} New{{camelCase .}}DataSource, {{- end}} - NewCLIDeviceTemplateDataSource, NewFeatureDeviceTemplateDataSource, } } diff --git a/internal/provider/data_source_sdwan_cli_device_template.go b/internal/provider/data_source_sdwan_cli_device_template.go index b3f961cf..4fde8fe8 100644 --- a/internal/provider/data_source_sdwan_cli_device_template.go +++ b/internal/provider/data_source_sdwan_cli_device_template.go @@ -15,13 +15,14 @@ // // SPDX-License-Identifier: MPL-2.0 +// Code generated by "gen/generator.go"; DO NOT EDIT. + package provider import ( "context" "fmt" - "github.com/CiscoDevNet/terraform-provider-sdwan/internal/provider/helpers" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-log/tflog" @@ -49,19 +50,23 @@ func (d *CLIDeviceTemplateDataSource) Metadata(_ context.Context, req datasource func (d *CLIDeviceTemplateDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { resp.Schema = schema.Schema{ // This description is used by the documentation generator and the language server. - MarkdownDescription: "This data source can read a CLI device template.", + MarkdownDescription: "This data source can read the CLI Device Template .", Attributes: map[string]schema.Attribute{ "id": schema.StringAttribute{ - MarkdownDescription: "The id of the deivce template", + MarkdownDescription: "The id of the object", Required: true, }, + "version": schema.Int64Attribute{ + MarkdownDescription: "The version of the object", + Computed: true, + }, "name": schema.StringAttribute{ MarkdownDescription: "The name of the device template", Computed: true, }, "description": schema.StringAttribute{ - MarkdownDescription: "The description of the feature template", + MarkdownDescription: "The description of the device template", Computed: true, }, "device_type": schema.StringAttribute{ @@ -69,11 +74,11 @@ func (d *CLIDeviceTemplateDataSource) Schema(ctx context.Context, req datasource Computed: true, }, "cli_type": schema.StringAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("CLI type").String, + MarkdownDescription: "CLI type", Computed: true, }, "cli_configuration": schema.StringAttribute{ - MarkdownDescription: helpers.NewAttributeDescription("CLI configuration").String, + MarkdownDescription: "CLI configuration", Computed: true, }, }, @@ -108,7 +113,7 @@ func (d *CLIDeviceTemplateDataSource) Read(ctx context.Context, req datasource.R config.fromBody(ctx, res) - tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", config.Name.ValueString())) + tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", config.Id.ValueString())) diags = resp.State.Set(ctx, &config) resp.Diagnostics.Append(diags...) diff --git a/internal/provider/data_source_sdwan_cli_device_template_test.go b/internal/provider/data_source_sdwan_cli_device_template_test.go index c3c298e9..0954740d 100644 --- a/internal/provider/data_source_sdwan_cli_device_template_test.go +++ b/internal/provider/data_source_sdwan_cli_device_template_test.go @@ -15,6 +15,8 @@ // // SPDX-License-Identifier: MPL-2.0 +// Code generated by "gen/generator.go"; DO NOT EDIT. + package provider import ( @@ -31,11 +33,11 @@ func TestAccDataSourceSdwanCLIDeviceTemplate(t *testing.T) { { Config: testAccDataSourceSdwanCLIDeviceTemplateConfig, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("data.sdwan_cli_device_template.test", "name", "TF_TEST_ALL"), - resource.TestCheckResourceAttr("data.sdwan_cli_device_template.test", "description", "Terraform integration test"), + resource.TestCheckResourceAttr("data.sdwan_cli_device_template.test", "name", "Example"), + resource.TestCheckResourceAttr("data.sdwan_cli_device_template.test", "description", "My description"), resource.TestCheckResourceAttr("data.sdwan_cli_device_template.test", "device_type", "vedge-ISR-4331"), resource.TestCheckResourceAttr("data.sdwan_cli_device_template.test", "cli_type", "device"), - resource.TestCheckResourceAttr("data.sdwan_cli_device_template.test", "cli_configuration", " system\n host-name {{test}}-ISR4331-1200-1"), + resource.TestCheckResourceAttr("data.sdwan_cli_device_template.test", "cli_configuration", " system\n host-name R1-ISR4331-1200-1"), ), }, }, @@ -44,12 +46,13 @@ func TestAccDataSourceSdwanCLIDeviceTemplate(t *testing.T) { const testAccDataSourceSdwanCLIDeviceTemplateConfig = ` + resource "sdwan_cli_device_template" "test" { - name = "TF_TEST_ALL" - description = "Terraform integration test" + name = "Example" + description = "My description" device_type = "vedge-ISR-4331" cli_type = "device" - cli_configuration = " system\n host-name {{test}}-ISR4331-1200-1" + cli_configuration = " system\n host-name R1-ISR4331-1200-1" } data "sdwan_cli_device_template" "test" { diff --git a/internal/provider/model_sdwan_cli_device_template.go b/internal/provider/model_sdwan_cli_device_template.go index 03aed9d1..5ff886f5 100644 --- a/internal/provider/model_sdwan_cli_device_template.go +++ b/internal/provider/model_sdwan_cli_device_template.go @@ -15,6 +15,8 @@ // // SPDX-License-Identifier: MPL-2.0 +// Code generated by "gen/generator.go"; DO NOT EDIT. + package provider import ( @@ -27,23 +29,33 @@ import ( type CLIDeviceTemplate struct { Id types.String `tfsdk:"id"` + Version types.Int64 `tfsdk:"version"` Name types.String `tfsdk:"name"` Description types.String `tfsdk:"description"` DeviceType types.String `tfsdk:"device_type"` - CLIType types.String `tfsdk:"cli_type"` - CLIConfiguration types.String `tfsdk:"cli_configuration"` + CliType types.String `tfsdk:"cli_type"` + CliConfiguration types.String `tfsdk:"cli_configuration"` } func (data CLIDeviceTemplate) toBody(ctx context.Context) string { body := "" - body, _ = sjson.Set(body, "templateName", data.Name.ValueString()) - body, _ = sjson.Set(body, "templateDescription", data.Description.ValueString()) - body, _ = sjson.Set(body, "deviceType", data.DeviceType.ValueString()) - body, _ = sjson.Set(body, "templateConfiguration", data.CLIConfiguration.ValueString()) - body, _ = sjson.Set(body, "factoryDefault", false) body, _ = sjson.Set(body, "configType", "file") - body, _ = sjson.Set(body, "cliType", data.CLIType.ValueString()) - body, _ = sjson.Set(body, "draftMode", false) + body, _ = sjson.Set(body, "factoryDefault", false) + if !data.Name.IsNull() { + body, _ = sjson.Set(body, "templateName", data.Name.ValueString()) + } + if !data.Description.IsNull() { + body, _ = sjson.Set(body, "templateDescription", data.Description.ValueString()) + } + if !data.DeviceType.IsNull() { + body, _ = sjson.Set(body, "deviceType", data.DeviceType.ValueString()) + } + if !data.CliType.IsNull() { + body, _ = sjson.Set(body, "cliType", data.CliType.ValueString()) + } + if !data.CliConfiguration.IsNull() { + body, _ = sjson.Set(body, "templateConfiguration", data.CliConfiguration.ValueString()) + } return body } @@ -63,14 +75,35 @@ func (data *CLIDeviceTemplate) fromBody(ctx context.Context, res gjson.Result) { } else { data.DeviceType = types.StringNull() } - if value := res.Get("templateConfiguration"); value.Exists() { - data.CLIConfiguration = types.StringValue(value.String()) + if value := res.Get("cliType"); value.Exists() { + data.CliType = types.StringValue(value.String()) } else { - data.CLIConfiguration = types.StringNull() + data.CliType = types.StringNull() } - if value := res.Get("cliType"); value.Exists() { - data.CLIType = types.StringValue(value.String()) + if value := res.Get("templateConfiguration"); value.Exists() { + data.CliConfiguration = types.StringValue(value.String()) } else { - data.CLIType = types.StringNull() + data.CliConfiguration = types.StringNull() + } + +} + +func (data *CLIDeviceTemplate) hasChanges(ctx context.Context, state *CLIDeviceTemplate) bool { + hasChanges := false + if !data.Name.Equal(state.Name) { + hasChanges = true + } + if !data.Description.Equal(state.Description) { + hasChanges = true + } + if !data.DeviceType.Equal(state.DeviceType) { + hasChanges = true + } + if !data.CliType.Equal(state.CliType) { + hasChanges = true + } + if !data.CliConfiguration.Equal(state.CliConfiguration) { + hasChanges = true } + return hasChanges } diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 461ddaf3..40b5e058 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -268,6 +268,7 @@ func (p *SdwanProvider) Resources(ctx context.Context) []func() resource.Resourc NewASPathListPolicyObjectResource, NewCflowdPolicyDefinitionResource, NewClassMapPolicyObjectResource, + NewCLIDeviceTemplateResource, NewColorListPolicyObjectResource, NewCustomControlTopologyPolicyDefinitionResource, NewDataIPv4PrefixListPolicyObjectResource, @@ -294,7 +295,6 @@ func (p *SdwanProvider) Resources(ctx context.Context) []func() resource.Resourc NewTrafficDataPolicyDefinitionResource, NewVPNListPolicyObjectResource, NewVPNMembershipPolicyDefinitionResource, - NewCLIDeviceTemplateResource, NewFeatureDeviceTemplateResource, NewAttachFeatureDeviceTemplateResource, } @@ -329,6 +329,7 @@ func (p *SdwanProvider) DataSources(ctx context.Context) []func() datasource.Dat NewASPathListPolicyObjectDataSource, NewCflowdPolicyDefinitionDataSource, NewClassMapPolicyObjectDataSource, + NewCLIDeviceTemplateDataSource, NewColorListPolicyObjectDataSource, NewCustomControlTopologyPolicyDefinitionDataSource, NewDataIPv4PrefixListPolicyObjectDataSource, @@ -355,7 +356,6 @@ func (p *SdwanProvider) DataSources(ctx context.Context) []func() datasource.Dat NewTrafficDataPolicyDefinitionDataSource, NewVPNListPolicyObjectDataSource, NewVPNMembershipPolicyDefinitionDataSource, - NewCLIDeviceTemplateDataSource, NewFeatureDeviceTemplateDataSource, } } diff --git a/internal/provider/resource_sdwan_cli_device_template.go b/internal/provider/resource_sdwan_cli_device_template.go index 83e892dd..bd6ee42e 100644 --- a/internal/provider/resource_sdwan_cli_device_template.go +++ b/internal/provider/resource_sdwan_cli_device_template.go @@ -15,11 +15,15 @@ // // SPDX-License-Identifier: MPL-2.0 +// Code generated by "gen/generator.go"; DO NOT EDIT. + package provider import ( "context" "fmt" + "strings" + "sync" "github.com/CiscoDevNet/terraform-provider-sdwan/internal/provider/helpers" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" @@ -43,7 +47,8 @@ func NewCLIDeviceTemplateResource() resource.Resource { } type CLIDeviceTemplateResource struct { - client *sdwan.Client + client *sdwan.Client + updateMutex *sync.Mutex } func (r *CLIDeviceTemplateResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { @@ -53,26 +58,30 @@ func (r *CLIDeviceTemplateResource) Metadata(ctx context.Context, req resource.M func (r *CLIDeviceTemplateResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { resp.Schema = schema.Schema{ // This description is used by the documentation generator and the language server. - MarkdownDescription: helpers.NewAttributeDescription("This resource can manage a CLI device template.").String, + MarkdownDescription: helpers.NewAttributeDescription("This resource can manage a CLI Device Template .").String, Attributes: map[string]schema.Attribute{ "id": schema.StringAttribute{ - MarkdownDescription: "The id of the device template", + MarkdownDescription: "The id of the object", Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), }, }, + "version": schema.Int64Attribute{ + MarkdownDescription: "The version of the object", + Computed: true, + }, "name": schema.StringAttribute{ - MarkdownDescription: "The name of the device template", + MarkdownDescription: helpers.NewAttributeDescription("The name of the device template").String, Required: true, }, "description": schema.StringAttribute{ - MarkdownDescription: "The description of the device template", + MarkdownDescription: helpers.NewAttributeDescription("The description of the device template").String, Required: true, }, "device_type": schema.StringAttribute{ - MarkdownDescription: "The device type (e.g., `vedge-ISR-4331`)", + MarkdownDescription: helpers.NewAttributeDescription("The device type (e.g., `vedge-ISR-4331`)").String, Required: true, }, "cli_type": schema.StringAttribute{ @@ -96,6 +105,7 @@ func (r *CLIDeviceTemplateResource) Configure(_ context.Context, req resource.Co } r.client = req.ProviderData.(*SdwanProviderData).Client + r.updateMutex = req.ProviderData.(*SdwanProviderData).UpdateMutex } func (r *CLIDeviceTemplateResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { @@ -113,13 +123,14 @@ func (r *CLIDeviceTemplateResource) Create(ctx context.Context, req resource.Cre // Create object body := plan.toBody(ctx) - res, err := r.client.Post("/template/device/cli", body) + res, err := r.client.Post("/template/device/cli/", body) if err != nil { resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (POST), got error: %s, %s", err, res.String())) return } plan.Id = types.StringValue(res.Get("templateId").String()) + plan.Version = types.Int64Value(0) tflog.Debug(ctx, fmt.Sprintf("%s: Create finished successfully", plan.Name.ValueString())) @@ -140,7 +151,7 @@ func (r *CLIDeviceTemplateResource) Read(ctx context.Context, req resource.ReadR tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", state.Name.String())) res, err := r.client.Get("/template/device/object/" + state.Id.ValueString()) - if res.Get("error.message").String() == "Invalid Template Id" { + if res.Get("error.message").String() == "Failed to find specified resource" { resp.State.RemoveResource(ctx) return } else if err != nil { @@ -157,7 +168,7 @@ func (r *CLIDeviceTemplateResource) Read(ctx context.Context, req resource.ReadR } func (r *CLIDeviceTemplateResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var plan CLIDeviceTemplate + var plan, state CLIDeviceTemplate // Read plan diags := req.Plan.Get(ctx, &plan) @@ -165,15 +176,32 @@ func (r *CLIDeviceTemplateResource) Update(ctx context.Context, req resource.Upd if resp.Diagnostics.HasError() { return } + // Read state + diags = req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Update", plan.Name.ValueString())) - body := plan.toBody(ctx) - res, err := r.client.Put("/template/device/"+plan.Id.ValueString(), body) - if err != nil { - resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (PUT), got error: %s, %s", err, res.String())) - return + if plan.hasChanges(ctx, &state) { + body := plan.toBody(ctx) + r.updateMutex.Lock() + res, err := r.client.Put("/template/device/"+plan.Id.ValueString(), body) + r.updateMutex.Unlock() + if err != nil { + if strings.Contains(res.Get("error.message").String(), "Failed to acquire lock") { + resp.Diagnostics.AddWarning("Client Warning", "Failed to modify policy due to policy being locked by another change. Policy changes will not be applied. Re-run 'terraform apply' to try again.") + } else { + resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (PUT), got error: %s, %s", err, res.String())) + return + } + } + } else { + tflog.Debug(ctx, fmt.Sprintf("%s: No changes detected", plan.Name.ValueString())) } + plan.Version = types.Int64Value(state.Version.ValueInt64() + 1) tflog.Debug(ctx, fmt.Sprintf("%s: Update finished successfully", plan.Name.ValueString())) @@ -194,7 +222,7 @@ func (r *CLIDeviceTemplateResource) Delete(ctx context.Context, req resource.Del tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Delete", state.Name.ValueString())) res, err := r.client.Delete("/template/device/" + state.Id.ValueString()) - if err != nil && res.Get("error.message").String() != "Invalid Template Id" { + if err != nil { resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to delete object (DELETE), got error: %s, %s", err, res.String())) return } diff --git a/internal/provider/resource_sdwan_cli_device_template_test.go b/internal/provider/resource_sdwan_cli_device_template_test.go index af10795b..9d5e5077 100644 --- a/internal/provider/resource_sdwan_cli_device_template_test.go +++ b/internal/provider/resource_sdwan_cli_device_template_test.go @@ -15,6 +15,8 @@ // // SPDX-License-Identifier: MPL-2.0 +// Code generated by "gen/generator.go"; DO NOT EDIT. + package provider import ( @@ -29,27 +31,27 @@ func TestAccSdwanCLIDeviceTemplate(t *testing.T) { ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { - Config: testAccSdwanCLIDeviceTemplateConfig_all(), + Config: testAccSdwanCLIDeviceTemplateConfig, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("sdwan_cli_device_template.test", "name", "TF_TEST_ALL"), - resource.TestCheckResourceAttr("sdwan_cli_device_template.test", "description", "Terraform integration test"), + resource.TestCheckResourceAttr("sdwan_cli_device_template.test", "name", "Example"), + resource.TestCheckResourceAttr("sdwan_cli_device_template.test", "description", "My description"), resource.TestCheckResourceAttr("sdwan_cli_device_template.test", "device_type", "vedge-ISR-4331"), resource.TestCheckResourceAttr("sdwan_cli_device_template.test", "cli_type", "device"), - resource.TestCheckResourceAttr("sdwan_cli_device_template.test", "cli_configuration", " system\n host-name {{test}}-ISR4331-1200-1"), + resource.TestCheckResourceAttr("sdwan_cli_device_template.test", "cli_configuration", " system\n host-name R1-ISR4331-1200-1"), ), }, }, }) } -func testAccSdwanCLIDeviceTemplateConfig_all() string { - return ` - resource "sdwan_cli_device_template" "test" { - name = "TF_TEST_ALL" - description = "Terraform integration test" - device_type = "vedge-ISR-4331" - cli_type = "device" - cli_configuration = " system\n host-name {{test}}-ISR4331-1200-1" - } - ` +const testAccSdwanCLIDeviceTemplateConfig = ` + + +resource "sdwan_cli_device_template" "test" { + name = "Example" + description = "My description" + device_type = "vedge-ISR-4331" + cli_type = "device" + cli_configuration = " system\n host-name R1-ISR4331-1200-1" } +`