From 17dce54fc8b688bbc8b3109927449d69e2584e69 Mon Sep 17 00:00:00 2001 From: Chuyi Ching Date: Tue, 27 Aug 2024 18:12:53 -0700 Subject: [PATCH 1/8] add new resource --- .../provider.tf | 1 + .../resource.tf | 9 + .../terraform.tfvars | 1 + .../variables.tf | 1 + internal/interfaces/security_login_message.go | 56 +--- internal/provider/provider.go | 1 + .../security_login_message_data_source.go | 4 +- .../security_login_message_resource.go | 277 ++++++++++++++++++ ...ty_security_login_message_resource_test.go | 74 +++++ internal/provider/tag_prefix_resource.go | 3 +- scripts/create_acc_test.bash | 5 +- scripts/create_data_source.bash | 4 +- scripts/create_resource.bash | 2 +- 13 files changed, 389 insertions(+), 49 deletions(-) create mode 120000 examples/resources/netapp-ontap_security_login_message/provider.tf create mode 100644 examples/resources/netapp-ontap_security_login_message/resource.tf create mode 120000 examples/resources/netapp-ontap_security_login_message/terraform.tfvars create mode 120000 examples/resources/netapp-ontap_security_login_message/variables.tf create mode 100644 internal/provider/security/security_login_message_resource.go create mode 100644 internal/provider/security/security_security_login_message_resource_test.go diff --git a/examples/resources/netapp-ontap_security_login_message/provider.tf b/examples/resources/netapp-ontap_security_login_message/provider.tf new file mode 120000 index 00000000..c6b7138f --- /dev/null +++ b/examples/resources/netapp-ontap_security_login_message/provider.tf @@ -0,0 +1 @@ +../../provider/provider.tf \ No newline at end of file diff --git a/examples/resources/netapp-ontap_security_login_message/resource.tf b/examples/resources/netapp-ontap_security_login_message/resource.tf new file mode 100644 index 00000000..92e0ba17 --- /dev/null +++ b/examples/resources/netapp-ontap_security_login_message/resource.tf @@ -0,0 +1,9 @@ + +resource "netapp-ontap_security_login_message" "msg_import_svm" { + banner = "test banner" + cx_profile_name = "cluster4" + message = "test message" + scope = "svm" + show_cluster_message = true + svm_name = "svm5" +} \ No newline at end of file diff --git a/examples/resources/netapp-ontap_security_login_message/terraform.tfvars b/examples/resources/netapp-ontap_security_login_message/terraform.tfvars new file mode 120000 index 00000000..8d9d1c96 --- /dev/null +++ b/examples/resources/netapp-ontap_security_login_message/terraform.tfvars @@ -0,0 +1 @@ +../../provider/terraform.tfvars \ No newline at end of file diff --git a/examples/resources/netapp-ontap_security_login_message/variables.tf b/examples/resources/netapp-ontap_security_login_message/variables.tf new file mode 120000 index 00000000..395ce618 --- /dev/null +++ b/examples/resources/netapp-ontap_security_login_message/variables.tf @@ -0,0 +1 @@ +../../provider/variables.tf \ No newline at end of file diff --git a/internal/interfaces/security_login_message.go b/internal/interfaces/security_login_message.go index 499160de..14a5ea51 100644 --- a/internal/interfaces/security_login_message.go +++ b/internal/interfaces/security_login_message.go @@ -9,13 +9,6 @@ import ( "github.com/netapp/terraform-provider-netapp-ontap/internal/utils" ) -// TODO: -// copy this file to match you data source (should match internal/interfaces/security_login_message.go) -// replace SecurityLoginMessage with the name of the resource, following go conventions, eg IPInterface -// replace security_login_message with the name of the resource, for logging purposes, eg ip_interface -// replace api_url with API, eg ip/interfaces -// delete these 5 lines - // SecurityLoginMessageGetDataModelONTAP describes the GET record data model using go types for mapping. type SecurityLoginMessageGetDataModelONTAP struct { Message string `mapstructure:"message"` @@ -26,10 +19,11 @@ type SecurityLoginMessageGetDataModelONTAP struct { UUID string `mapstructure:"uuid"` } -// SecurityLoginMessageResourceBodyDataModelONTAP describes the body data model using go types for mapping. +// SecurityLoginMessageResourceBodyDataModelONTAP describes the body data model using go types for mapping. Both svm and scope are not allowed to be updated. type SecurityLoginMessageResourceBodyDataModelONTAP struct { - Name string `mapstructure:"name"` - SVM svm `mapstructure:"svm"` + Banner string `mapstructure:"banner"` + Message string `mapstructure:"message"` + ShowClusterMessage bool `mapstructure:"show_cluster_message"` } // SecurityLoginMessageDataSourceFilterModel describes the data source data model for queries. @@ -40,17 +34,12 @@ type SecurityLoginMessageDataSourceFilterModel struct { SVMName string `mapstructure:"svm.name"` } -// GetSecurityLoginMessageByBannerMotd to get security_login_message info -// Retrieves the login banner and messages of the day (MOTD) configured in the cluster and in specific SVMs. -func GetSecurityLoginMessageByBannerMotd(errorHandler *utils.ErrorHandler, r restclient.RestClient, banner string, message string, svmName string) (*SecurityLoginMessageGetDataModelONTAP, error) { +// GetSecurityLoginMessage to get security_login_message info +// Retrieves the login banner and messages of the day (MOTD) configured in the cluster and in a specific SVM. +func GetSecurityLoginMessage(errorHandler *utils.ErrorHandler, r restclient.RestClient, svmName string) (*SecurityLoginMessageGetDataModelONTAP, error) { api := "security/login/messages" query := r.NewQuery() - if message != "" { - query.Set("message", message) - } - if banner != "" { - query.Set("banner", banner) - } + if svmName == "" { query.Set("scope", "cluster") } else { @@ -108,34 +97,19 @@ func GetSecurityLoginMessages(errorHandler *utils.ErrorHandler, r restclient.Res return dataONTAP, nil } -// CreateSecurityLoginMessage to create security_login_message -func CreateSecurityLoginMessage(errorHandler *utils.ErrorHandler, r restclient.RestClient, body SecurityLoginMessageResourceBodyDataModelONTAP) (*SecurityLoginMessageGetDataModelONTAP, error) { - api := "api_url" +// UpdateSecurityLoginMessage to update security_login_message +func UpdateSecurityLoginMessage(errorHandler *utils.ErrorHandler, r restclient.RestClient, uuid string, body SecurityLoginMessageResourceBodyDataModelONTAP) error { + api := "security/login/messages" var bodyMap map[string]interface{} if err := mapstructure.Decode(body, &bodyMap); err != nil { - return nil, errorHandler.MakeAndReportError("error encoding security_login_message body", fmt.Sprintf("error on encoding %s body: %s, body: %#v", api, err, body)) + return errorHandler.MakeAndReportError("error encoding security_login_message body", fmt.Sprintf("error on encoding %s body: %s, body: %#v", api, err, body)) } + tflog.Debug(errorHandler.Ctx, fmt.Sprintf("Update security login message: %#v", body)) query := r.NewQuery() query.Add("return_records", "true") - statusCode, response, err := r.CallCreateMethod(api, query, bodyMap) - if err != nil { - return nil, errorHandler.MakeAndReportError("error creating security_login_message", fmt.Sprintf("error on POST %s: %s, statusCode %d", api, err, statusCode)) - } - - var dataONTAP SecurityLoginMessageGetDataModelONTAP - if err := mapstructure.Decode(response.Records[0], &dataONTAP); err != nil { - return nil, errorHandler.MakeAndReportError("error decoding security_login_message info", fmt.Sprintf("error on decode storage/security_login_messages info: %s, statusCode %d, response %#v", err, statusCode, response)) - } - tflog.Debug(errorHandler.Ctx, fmt.Sprintf("Create security_login_message source - udata: %#v", dataONTAP)) - return &dataONTAP, nil -} - -// DeleteSecurityLoginMessage to delete security_login_message -func DeleteSecurityLoginMessage(errorHandler *utils.ErrorHandler, r restclient.RestClient, uuid string) error { - api := "api_url" - statusCode, _, err := r.CallDeleteMethod(api+"/"+uuid, nil, nil) + statusCode, _, err := r.CallUpdateMethod(api+"/"+uuid, query, bodyMap) if err != nil { - return errorHandler.MakeAndReportError("error deleting security_login_message", fmt.Sprintf("error on DELETE %s: %s, statusCode %d", api, err, statusCode)) + return errorHandler.MakeAndReportError("error updating security_login_message", fmt.Sprintf("error on PUT %s: %s, statusCode %d", api, err, statusCode)) } return nil } diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 34711790..01f53572 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -174,6 +174,7 @@ func (p *ONTAPProvider) Resources(ctx context.Context) []func() resource.Resourc protocols.NewProtocolsSanIgroupResource, protocols.NewProtocolsSanLunMapsResource, security.NewSecurityAccountResource, + security.NewSecurityLoginMessageResource, snapmirror.NewSnapmirrorResource, snapmirror.NewSnapmirrorPolicyResource, storage.NewStorageLunResource, diff --git a/internal/provider/security/security_login_message_data_source.go b/internal/provider/security/security_login_message_data_source.go index f25c5951..a68f5539 100644 --- a/internal/provider/security/security_login_message_data_source.go +++ b/internal/provider/security/security_login_message_data_source.go @@ -59,7 +59,7 @@ func (d *SecurityLoginMessageDataSource) Schema(ctx context.Context, req datasou Required: true, }, "message": schema.StringAttribute{ - MarkdownDescription: "SecurityLoginMessage name", + MarkdownDescription: "SecurityLoginMessage message", Optional: true, Computed: true, }, @@ -126,7 +126,7 @@ func (d *SecurityLoginMessageDataSource) Read(ctx context.Context, req datasourc return } - restInfo, err := interfaces.GetSecurityLoginMessageByBannerMotd(errorHandler, *client, data.Banner.ValueString(), data.Message.ValueString(), data.SVMName.ValueString()) + restInfo, err := interfaces.GetSecurityLoginMessage(errorHandler, *client, data.SVMName.ValueString()) if err != nil { // error reporting done inside GetSecurityLoginMessage return diff --git a/internal/provider/security/security_login_message_resource.go b/internal/provider/security/security_login_message_resource.go new file mode 100644 index 00000000..88973ec8 --- /dev/null +++ b/internal/provider/security/security_login_message_resource.go @@ -0,0 +1,277 @@ +package security + +import ( + "context" + "fmt" + "strings" + + "github.com/netapp/terraform-provider-netapp-ontap/internal/provider/connection" + + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/netapp/terraform-provider-netapp-ontap/internal/interfaces" + "github.com/netapp/terraform-provider-netapp-ontap/internal/utils" +) + +// Ensure provider defined types fully satisfy framework interfaces +var _ resource.Resource = &SecurityLoginMessageResource{} +var _ resource.ResourceWithImportState = &SecurityLoginMessageResource{} + +// NewSecurityLoginMessageResource is a helper function to simplify the provider implementation. +func NewSecurityLoginMessageResource() resource.Resource { + return &SecurityLoginMessageResource{ + config: connection.ResourceOrDataSourceConfig{ + Name: "security_login_message", + }, + } +} + +// SecurityLoginMessageResource defines the resource implementation. +type SecurityLoginMessageResource struct { + config connection.ResourceOrDataSourceConfig +} + +// SecurityLoginMessageResourceModel describes the resource data model. +type SecurityLoginMessageResourceModel struct { + CxProfileName types.String `tfsdk:"cx_profile_name"` + Banner types.String `tfsdk:"banner"` + Message types.String `tfsdk:"message"` + ShowClusterMessage types.Bool `tfsdk:"show_cluster_message"` + Scope types.String `tfsdk:"scope"` + SVMName types.String `tfsdk:"svm_name"` + ID types.String `tfsdk:"id"` +} + +// Metadata returns the resource type name. +func (r *SecurityLoginMessageResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_" + r.config.Name +} + +// Schema defines the schema for the resource. +func (r *SecurityLoginMessageResource) 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: "SecurityLoginMessage resource", + + Attributes: map[string]schema.Attribute{ + "cx_profile_name": schema.StringAttribute{ + MarkdownDescription: "Connection profile name", + Required: true, + }, + "svm_name": schema.StringAttribute{ + MarkdownDescription: "SecurityLoginMessage svm name", + Optional: true, + }, + "message": schema.StringAttribute{ + MarkdownDescription: "SecurityLoginMessage message", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "banner": schema.StringAttribute{ + MarkdownDescription: "SecurityLoginMessage banner", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "show_cluster_message": schema.BoolAttribute{ + MarkdownDescription: "Specifies whether to show a cluster-level message before the SVM message when logging in as an SVM administrator", + Optional: true, + Computed: true, + }, + "scope": schema.StringAttribute{ + MarkdownDescription: "SecurityLoginMessage scope", + Optional: true, + Computed: true, + }, + "id": schema.StringAttribute{ + MarkdownDescription: "SecurityLoginMessage ID", + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + }, + } +} + +// Configure adds the provider configured client to the resource. +func (r *SecurityLoginMessageResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + config, ok := req.ProviderData.(connection.Config) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected Config, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + } + r.config.ProviderConfig = config +} + +// Read refreshes the Terraform state with the latest data. +func (r *SecurityLoginMessageResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var data SecurityLoginMessageResourceModel + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + errorHandler := utils.NewErrorHandler(ctx, &resp.Diagnostics) + // we need to defer setting the client until we can read the connection profile name + client, err := connection.GetRestClient(errorHandler, r.config, data.CxProfileName) + if err != nil { + // error reporting done inside NewClient + return + } + + restInfo, err := interfaces.GetSecurityLoginMessage(errorHandler, *client, data.SVMName.ValueString()) + if err != nil { + // error reporting done inside GetSecurityLoginMessage + return + } + // Remove trailing newline characters from Message and Banner since the newline always is added at the end + cleanMessage := strings.TrimSuffix(restInfo.Message, "\n") + cleanBanner := strings.TrimSuffix(restInfo.Banner, "\n") + // Set the values from the response into the data model + data.Message = types.StringValue(cleanMessage) + data.Banner = types.StringValue(cleanBanner) + data.ShowClusterMessage = types.BoolValue(restInfo.ShowClusterMessage) + data.Scope = types.StringValue(restInfo.Scope) + data.ID = types.StringValue(restInfo.UUID) + + // Write logs using the tflog package + // Documentation: https://terraform.io/plugin/log + tflog.Debug(ctx, fmt.Sprintf("read a resource: %#v", data)) + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +// Create a resource and retrieve UUID +func (r *SecurityLoginMessageResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var data *SecurityLoginMessageResourceModel + + // Read Terraform plan data into the model + resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // Add an error diagnostic indicating that Create is not supported + resp.Diagnostics.AddError( + "Create Not Supported", + "The create operation is not supported for the security_login_message resource. Please import an existing resource instead.", + ) + + tflog.Error(ctx, "Create not supported for resource security_login_message") +} + +// Update updates the resource and sets the updated Terraform state on success. +func (r *SecurityLoginMessageResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var plan, state *SecurityLoginMessageResourceModel + + // Read Terraform plan data into the model + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + errorHandler := utils.NewErrorHandler(ctx, &resp.Diagnostics) + + client, err := connection.GetRestClient(utils.NewErrorHandler(ctx, &resp.Diagnostics), r.config, plan.CxProfileName) + if err != nil { + // error reporting done inside NewClient + return + } + + var request interfaces.SecurityLoginMessageResourceBodyDataModelONTAP + + request.Banner = plan.Banner.ValueString() + request.Message = plan.Message.ValueString() + request.ShowClusterMessage = plan.ShowClusterMessage.ValueBool() + + if request.Message == "" && request.ShowClusterMessage { + resp.Diagnostics.AddError("Invalid Input", "Message must be set when ShowClusterMessage is true") + return + } + err = interfaces.UpdateSecurityLoginMessage(errorHandler, *client, state.ID.ValueString(), request) + if err != nil { + // error reporting done inside UpdateSecurityLoginMessage + return + } + // Read the updated data from the API + restInfo, err := interfaces.GetSecurityLoginMessage(errorHandler, *client, plan.SVMName.ValueString()) + if err != nil { + // error reporting done inside GetSecurityLoginMessage + return + } + plan.ShowClusterMessage = types.BoolValue(restInfo.ShowClusterMessage) + plan.Scope = types.StringValue(restInfo.Scope) + + // Save updated data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) +} + +// Delete deletes the resource and removes the Terraform state on success. +func (r *SecurityLoginMessageResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var data *SecurityLoginMessageResourceModel + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // Add an error diagnostic indicating that Delete is not supported + resp.Diagnostics.AddError( + "Delete Not Supported", + "The update operation is not supported for the security_login_message resource.", + ) + + tflog.Error(ctx, "Delete not supported for resource security_login_message") +} + +// ImportState imports a resource using ID from terraform import command by calling the Read method. +func (r *SecurityLoginMessageResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + tflog.Debug(ctx, fmt.Sprintf("import req security login message resource: %#v", req)) + idParts := strings.Split(req.ID, ",") + + // import cx_profile only + if len(idParts) == 1 { + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("cx_profile_name"), idParts[0])...) + return + } + // import svm and cx_profile + if len(idParts) == 2 { + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("svm_name"), idParts[0])...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("cx_profile_name"), idParts[1])...) + return + } + + resp.Diagnostics.AddError( + "Unexpected Import Identifier", + fmt.Sprintf("Expected import identifier with format: svm_name,cx_profile_name. Got: %q", req.ID), + ) +} diff --git a/internal/provider/security/security_security_login_message_resource_test.go b/internal/provider/security/security_security_login_message_resource_test.go new file mode 100644 index 00000000..cf5aec2a --- /dev/null +++ b/internal/provider/security/security_security_login_message_resource_test.go @@ -0,0 +1,74 @@ +package security_test + +import ( + "fmt" + "os" + "regexp" + "testing" + + ntest "github.com/netapp/terraform-provider-netapp-ontap/internal/provider" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccSecurityLoginMessage(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { ntest.TestAccPreCheck(t) }, + ProtoV6ProviderFactories: ntest.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Creating security_login_message test + { + Config: testAccSecurityLoginMessageBasicClusterConfig(), + ExpectError: regexp.MustCompile("create operation is not supported"), + }, + // Import and read with cluster + { + ResourceName: "netapp-ontap_security_login_message.example", + ImportState: true, + ImportStateId: "cluster1", + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_security_login_message.example", "scope", "cluster"), + ), + }, + // Import and read with svm + { + ResourceName: "netapp-ontap_security_login_message.example", + ImportState: true, + ImportStateId: "svm5,cluster1", + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_security_login_message.example", "scope", "svm"), + ), + }, + // Update a option cannot tested in acc test + // Delete testing automatically occurs in TestCase + }, + }) +} + +func testAccSecurityLoginMessageBasicClusterConfig() string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster1" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_security_login_message" "example" { + cx_profile_name = "cluster1" + message = "Test cluster only \n message\n on the cluster" + show_cluster_message = true +}`, host, admin, password) +} diff --git a/internal/provider/tag_prefix_resource.go b/internal/provider/tag_prefix_resource.go index af9fa019..8953ae32 100644 --- a/internal/provider/tag_prefix_resource.go +++ b/internal/provider/tag_prefix_resource.go @@ -3,6 +3,7 @@ package provider import ( "context" "fmt" + "github.com/netapp/terraform-provider-netapp-ontap/internal/provider/connection" "github.com/hashicorp/terraform-plugin-framework/path" @@ -31,7 +32,7 @@ var _ resource.ResourceWithImportState = &GoPrefixResource{} func NewGoPrefixResource() resource.Resource { return &GoPrefixResource{ config: connection.ResourceOrDataSourceConfig{ - Name: "tag_prefix_resource", + Name: "tag_prefix", }, } } diff --git a/scripts/create_acc_test.bash b/scripts/create_acc_test.bash index 70252305..6ad8c2d8 100755 --- a/scripts/create_acc_test.bash +++ b/scripts/create_acc_test.bash @@ -45,8 +45,8 @@ cp "internal/provider/snapmirror/${existing_resource_name}_test.go" "${new_test_ # Replace all occurrences of the existing resource name with the new resource name in the new test file sed -i -e "s/${existing_resource_name}/${new_resource_name}/g" "${new_test_file}" - -sed -i -e "114,115d;111,112d;108,109d;79,80d;76,77d;18,22d;" "${new_test_file}" +sed -i '' "s/package snapmirror_test/package ${path_for_file}_test/g" "${new_test_file}" +sed -i -e "114,115d;111,112d;108,109d;79,80d;76,77d;" "${new_test_file}" sed -i -e "s/SnapmirrorResource/${go_prefix}/g" "${new_test_file}" sed -i -e "s/snapmirror_dest_svm:testme/name/g" "${new_test_file}" sed -i -e "s/snapmirror_source_svm:snap3/acc_test/g" "${new_test_file}" @@ -64,6 +64,7 @@ sed -i -e "s/policy = {/option_name = \"%s\"/g" "${new_test_file}" sed -i -e "s/policy/option/g" "${new_test_file}" sed -i -e "s/snapmirror/${new_test_file_name}/g" "${new_test_file}" + rm -rf $bad_test_file echo "Done." \ No newline at end of file diff --git a/scripts/create_data_source.bash b/scripts/create_data_source.bash index c7e1ce8a..ed497297 100755 --- a/scripts/create_data_source.bash +++ b/scripts/create_data_source.bash @@ -88,7 +88,7 @@ else link_if_exist ../../provider/variables.tf link_if_exist ../../provider/terraform.tfvars cat > data-source.tf << EOF -data "netapp-ontap_${tag_prefix}_data_source" "${tag_prefix}" { +data "netapp-ontap_${tag_prefix}" "${tag_prefix}" { # required to know which system to interface with cx_profile_name = "cluster1" name = "testme" @@ -109,7 +109,7 @@ else link_if_exist ../../provider/variables.tf link_if_exist ../../provider/terraform.tfvars cat > data-source.tf << EOF -data "netapp-ontap_${tag_all_prefix}_data_source" "${tag_all_prefix}" { +data "netapp-ontap_${tag_all_prefix}" "${tag_all_prefix}" { # required to know which system to interface with cx_profile_name = "cluster1" # filter = {} diff --git a/scripts/create_resource.bash b/scripts/create_resource.bash index 008732d7..c07084ae 100755 --- a/scripts/create_resource.bash +++ b/scripts/create_resource.bash @@ -72,7 +72,7 @@ else link_if_exist ../../provider/variables.tf link_if_exist ../../provider/terraform.tfvars cat > resource.tf << EOF -resource "netapp-ontap_${tag_prefix}_resource" "${tag_prefix}" { +resource "netapp-ontap_${tag_prefix}" "${tag_prefix}" { # required to know which system to interface with cx_profile_name = "cluster1" name = "testme" From b49671e093ff83f05107e7640c094cf4e5cf4be1 Mon Sep 17 00:00:00 2001 From: Chuyi Ching Date: Wed, 28 Aug 2024 10:02:52 -0700 Subject: [PATCH 2/8] add docs --- CHANGELOG.md | 1 + docs/resources/security_login_message.md | 103 ++++++++++++++++++ .../resource.tf | 8 ++ .../security_login_message_resource.go | 6 +- scripts/generate_docs.py | 1 + 5 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 docs/resources/security_login_message.md diff --git a/CHANGELOG.md b/CHANGELOG.md index d3d06f18..f1324f73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ FEATURES: * **New Resource:** `netapp-ontap_volume_efficiency_policies` ([#80](https://github.com/NetApp/terraform-provider-netapp-ontap/issues/80)) * **New Resource:** `netapp-ontap_quota_rules` ([#136](https://github.com/NetApp/terraform-provider-netapp-ontap/issues/136)) * **New Resource:** `netapp-ontap_volumes_files` ([#5](https://github.com/NetApp/terraform-provider-netapp-ontap/issues/5)) +* **New Resource:** `netapp-security_login_message` ([#18](https://github.com/NetApp/terraform-provider-netapp-ontap/issues/18)) ENHANCEMENTS: * **netapp-ontap_lun**: added `size_unit` option. ([#227](https://github.com/NetApp/terraform-provider-netapp-ontap/issues/227)) diff --git a/docs/resources/security_login_message.md b/docs/resources/security_login_message.md new file mode 100644 index 00000000..ac0d7c8b --- /dev/null +++ b/docs/resources/security_login_message.md @@ -0,0 +1,103 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "netapp-ontap_security_login_message Resource - terraform-provider-netapp-ontap" +subcategory: "Security" +description: |- + SecurityLoginMessage resource +--- + +# Resource security login message + +Update/Import Security Login Message + +### Related ONTAP commands +```commandline +* security login banner show +* security login motd show +* security login banner modify +* security login motd modify +``` + +## Supported Platforms +* On-perm ONTAP system 9.6 or higher + +## Example Usage + +```terraform +resource "netapp-ontap_security_login_message" "msg_import_cluster" { + banner = "test banner" + cx_profile_name = "cluster4" + message = "test message" + scope = "cluster" + show_cluster_message = true +} + +resource "netapp-ontap_security_login_message" "msg_import_svm" { + banner = "test banner" + cx_profile_name = "cluster4" + message = "test message" + scope = "svm" + show_cluster_message = true + svm_name = "svm5" +} +``` + + +## Schema + +### Required + +- `cx_profile_name` (String) Connection profile name + +### Optional + +- `banner` (String) SecurityLoginMessage login banner +- `message` (String) SecurityLoginMessage the message of the day (MOTD). This message appears just before the clustershell prompt after a successful login. +- `scope` (String) SecurityLoginMessage network scope +- `show_cluster_message` (Boolean) Specifies whether to show a cluster-level message before the SVM message when logging in as an SVM administrator +- `svm_name` (String) SecurityLoginMessage svm name + +### Read-Only + +- `id` (String) SecurityLoginMessage ID + +### Terraform Import + + For example + Import with cluster info only + ```shell + terraform import netapp-ontap_security_login_message.cluster_import cluster4 + ``` +Import with svm and cluster info + ```shell + terraform import netapp-ontap_security_login_message.svm_import svm1,cluster4 + ``` + +### Terraform Import Block +This requires Terraform 1.5 or higher, and will auto create the configuration for you + +First create the block. Use import svm message as an example +```terraform +import { + to = netapp-ontap_security_login_message.svm_import + id = "svm1,cluster4" +} +``` +Next run, this will auto create the configuration for you +```shell +terraform plan -generate-config-out=generated.tf +``` +This will generate a file called generated.tf, which will contain the configuration for the imported resource +```terraform +# __generated__ by Terraform +# Please review these resources and move them into your main configuration files. +# __generated__ by Terraform from "svm1,cluster4" +resource "netapp-ontap_security_login_message" "msg_import_svm" { + banner = "test banner" + cx_profile_name = "cluster4" + message = "test message\n12345" + scope = "svm" + show_cluster_message = true + svm_name = "svm1" +} +``` \ No newline at end of file diff --git a/examples/resources/netapp-ontap_security_login_message/resource.tf b/examples/resources/netapp-ontap_security_login_message/resource.tf index 92e0ba17..b6ed0f1c 100644 --- a/examples/resources/netapp-ontap_security_login_message/resource.tf +++ b/examples/resources/netapp-ontap_security_login_message/resource.tf @@ -1,4 +1,12 @@ +resource "netapp-ontap_security_login_message" "msg_import_cluster" { + banner = "test banner" + cx_profile_name = "cluster4" + message = "test message" + scope = "cluster" + show_cluster_message = true +} + resource "netapp-ontap_security_login_message" "msg_import_svm" { banner = "test banner" cx_profile_name = "cluster4" diff --git a/internal/provider/security/security_login_message_resource.go b/internal/provider/security/security_login_message_resource.go index 88973ec8..3bacf37f 100644 --- a/internal/provider/security/security_login_message_resource.go +++ b/internal/provider/security/security_login_message_resource.go @@ -68,7 +68,7 @@ func (r *SecurityLoginMessageResource) Schema(ctx context.Context, req resource. Optional: true, }, "message": schema.StringAttribute{ - MarkdownDescription: "SecurityLoginMessage message", + MarkdownDescription: "SecurityLoginMessage the message of the day (MOTD). This message appears just before the clustershell prompt after a successful login.", Optional: true, Computed: true, PlanModifiers: []planmodifier.String{ @@ -76,7 +76,7 @@ func (r *SecurityLoginMessageResource) Schema(ctx context.Context, req resource. }, }, "banner": schema.StringAttribute{ - MarkdownDescription: "SecurityLoginMessage banner", + MarkdownDescription: "SecurityLoginMessage login banner", Optional: true, Computed: true, PlanModifiers: []planmodifier.String{ @@ -89,7 +89,7 @@ func (r *SecurityLoginMessageResource) Schema(ctx context.Context, req resource. Computed: true, }, "scope": schema.StringAttribute{ - MarkdownDescription: "SecurityLoginMessage scope", + MarkdownDescription: "SecurityLoginMessage network scope", Optional: true, Computed: true, }, diff --git a/scripts/generate_docs.py b/scripts/generate_docs.py index 4c0a24af..98ac6719 100755 --- a/scripts/generate_docs.py +++ b/scripts/generate_docs.py @@ -79,6 +79,7 @@ "security_account_resource.md", "security_login_message_data_source.md", "security_login_messages_data_source.md", + "security_login_message_resource.md", ], 'snaplock': [], 'snapmirror': [ From 99c5c6e7ca0532e83de8c019ab243ce62267a64a Mon Sep 17 00:00:00 2001 From: Chuyi Ching Date: Wed, 28 Aug 2024 16:50:04 -0700 Subject: [PATCH 3/8] fix acc test on cifs share resource test --- .../protocols/protocols_cifs_share_resource_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/provider/protocols/protocols_cifs_share_resource_test.go b/internal/provider/protocols/protocols_cifs_share_resource_test.go index 56e8fb9f..e23a7ea3 100644 --- a/internal/provider/protocols/protocols_cifs_share_resource_test.go +++ b/internal/provider/protocols/protocols_cifs_share_resource_test.go @@ -89,7 +89,7 @@ resource "netapp-ontap_cifs_share" "example" { cx_profile_name = "clustercifs" name = "%s" svm_name = "%s" - path = "/acc_test_cifs_share_volume" + path = "/" acls = [ { "permission": "read", @@ -127,7 +127,7 @@ resource "netapp-ontap_cifs_share" "example" { cx_profile_name = "clustercifs" name = "%s" svm_name = "%s" - path = "/acc_test_cifs_share_volume" + path = "/" acls = [ { "permission": "full_control", @@ -166,7 +166,7 @@ resource "netapp-ontap_cifs_share" "example" { cx_profile_name = "clustercifs" name = "%s" svm_name = "%s" - path = "/acc_test_cifs_share_volume" + path = "/" acls = [ { "permission": "read", @@ -210,7 +210,7 @@ resource "netapp-ontap_cifs_share" "example" { cx_profile_name = "clustercifs" name = "%s" svm_name = "%s" - path = "/acc_test_cifs_share_volume" + path = "/" acls = [ { "permission": "read", From 4b71a052f4aadd3f81361e085ba347ecbbb6cebd Mon Sep 17 00:00:00 2001 From: Chuyi Ching Date: Wed, 28 Aug 2024 17:13:24 -0700 Subject: [PATCH 4/8] fix doc to make reading easily --- docs/resources/security_login_message.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/resources/security_login_message.md b/docs/resources/security_login_message.md index ac0d7c8b..9efef804 100644 --- a/docs/resources/security_login_message.md +++ b/docs/resources/security_login_message.md @@ -9,6 +9,7 @@ description: |- # Resource security login message Update/Import Security Login Message +The `security_login_message` resource does not support creation or deletion operations. Users must first import the existing resource and then perform updates as needed. ### Related ONTAP commands ```commandline From b6397d5ed94b31da88e9f84ad1dc4099c53d4e82 Mon Sep 17 00:00:00 2001 From: Chuyi Ching Date: Thu, 29 Aug 2024 13:21:05 -0700 Subject: [PATCH 5/8] fix naming issue --- docs/resources/security_login_message.md | 16 ++++++++-------- .../resource.tf | 6 +++--- internal/interfaces/security_login_message.go | 10 +++++----- .../security/security_login_message_resource.go | 4 ++-- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/resources/security_login_message.md b/docs/resources/security_login_message.md index 9efef804..d22d3834 100644 --- a/docs/resources/security_login_message.md +++ b/docs/resources/security_login_message.md @@ -1,6 +1,6 @@ --- # generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "netapp-ontap_security_login_message Resource - terraform-provider-netapp-ontap" +page_title: "netapp-ontap_security_login_messages Resource - terraform-provider-netapp-ontap" subcategory: "Security" description: |- SecurityLoginMessage resource @@ -9,7 +9,7 @@ description: |- # Resource security login message Update/Import Security Login Message -The `security_login_message` resource does not support creation or deletion operations. Users must first import the existing resource and then perform updates as needed. +The `security_login_messages` resource does not support creation or deletion operations. Users must first import the existing resource and then perform updates as needed. ### Related ONTAP commands ```commandline @@ -25,7 +25,7 @@ The `security_login_message` resource does not support creation or deletion oper ## Example Usage ```terraform -resource "netapp-ontap_security_login_message" "msg_import_cluster" { +resource "netapp-ontap_security_login_messages" "msg_import_cluster" { banner = "test banner" cx_profile_name = "cluster4" message = "test message" @@ -33,7 +33,7 @@ resource "netapp-ontap_security_login_message" "msg_import_cluster" { show_cluster_message = true } -resource "netapp-ontap_security_login_message" "msg_import_svm" { +resource "netapp-ontap_security_login_messages" "msg_import_svm" { banner = "test banner" cx_profile_name = "cluster4" message = "test message" @@ -67,11 +67,11 @@ resource "netapp-ontap_security_login_message" "msg_import_svm" { For example Import with cluster info only ```shell - terraform import netapp-ontap_security_login_message.cluster_import cluster4 + terraform import netapp-ontap_security_login_messages.cluster_import cluster4 ``` Import with svm and cluster info ```shell - terraform import netapp-ontap_security_login_message.svm_import svm1,cluster4 + terraform import netapp-ontap_security_login_messages.svm_import svm1,cluster4 ``` ### Terraform Import Block @@ -80,7 +80,7 @@ This requires Terraform 1.5 or higher, and will auto create the configuration fo First create the block. Use import svm message as an example ```terraform import { - to = netapp-ontap_security_login_message.svm_import + to = netapp-ontap_security_login_messages.svm_import id = "svm1,cluster4" } ``` @@ -93,7 +93,7 @@ This will generate a file called generated.tf, which will contain the configurat # __generated__ by Terraform # Please review these resources and move them into your main configuration files. # __generated__ by Terraform from "svm1,cluster4" -resource "netapp-ontap_security_login_message" "msg_import_svm" { +resource "netapp-ontap_security_login_messages" "msg_import_svm" { banner = "test banner" cx_profile_name = "cluster4" message = "test message\n12345" diff --git a/examples/resources/netapp-ontap_security_login_message/resource.tf b/examples/resources/netapp-ontap_security_login_message/resource.tf index b6ed0f1c..d04d7002 100644 --- a/examples/resources/netapp-ontap_security_login_message/resource.tf +++ b/examples/resources/netapp-ontap_security_login_message/resource.tf @@ -1,5 +1,5 @@ -resource "netapp-ontap_security_login_message" "msg_import_cluster" { +resource "netapp-ontap_security_login_messages" "msg_import_cluster" { banner = "test banner" cx_profile_name = "cluster4" message = "test message" @@ -7,11 +7,11 @@ resource "netapp-ontap_security_login_message" "msg_import_cluster" { show_cluster_message = true } -resource "netapp-ontap_security_login_message" "msg_import_svm" { +resource "netapp-ontap_security_login_messages" "msg_import_svm" { banner = "test banner" cx_profile_name = "cluster4" message = "test message" scope = "svm" show_cluster_message = true svm_name = "svm5" -} \ No newline at end of file +} diff --git a/internal/interfaces/security_login_message.go b/internal/interfaces/security_login_message.go index 14a5ea51..ab4754aa 100644 --- a/internal/interfaces/security_login_message.go +++ b/internal/interfaces/security_login_message.go @@ -64,7 +64,7 @@ func GetSecurityLoginMessage(errorHandler *utils.ErrorHandler, r restclient.Rest return &dataONTAP, nil } -// GetSecurityLoginMessages to get security_login_message info for all resources matching a filter +// GetSecurityLoginMessages to get security_login_messages info for all resources matching a filter func GetSecurityLoginMessages(errorHandler *utils.ErrorHandler, r restclient.RestClient, filter *SecurityLoginMessageDataSourceFilterModel) ([]SecurityLoginMessageGetDataModelONTAP, error) { api := "security/login/messages" query := r.NewQuery() @@ -97,19 +97,19 @@ func GetSecurityLoginMessages(errorHandler *utils.ErrorHandler, r restclient.Res return dataONTAP, nil } -// UpdateSecurityLoginMessage to update security_login_message +// UpdateSecurityLoginMessage to update security_login_messages func UpdateSecurityLoginMessage(errorHandler *utils.ErrorHandler, r restclient.RestClient, uuid string, body SecurityLoginMessageResourceBodyDataModelONTAP) error { api := "security/login/messages" var bodyMap map[string]interface{} if err := mapstructure.Decode(body, &bodyMap); err != nil { - return errorHandler.MakeAndReportError("error encoding security_login_message body", fmt.Sprintf("error on encoding %s body: %s, body: %#v", api, err, body)) + return errorHandler.MakeAndReportError("error encoding security_login_messages body", fmt.Sprintf("error on encoding %s body: %s, body: %#v", api, err, body)) } - tflog.Debug(errorHandler.Ctx, fmt.Sprintf("Update security login message: %#v", body)) + tflog.Debug(errorHandler.Ctx, fmt.Sprintf("Update security login messages: %#v", body)) query := r.NewQuery() query.Add("return_records", "true") statusCode, _, err := r.CallUpdateMethod(api+"/"+uuid, query, bodyMap) if err != nil { - return errorHandler.MakeAndReportError("error updating security_login_message", fmt.Sprintf("error on PUT %s: %s, statusCode %d", api, err, statusCode)) + return errorHandler.MakeAndReportError("error updating security_login_messages", fmt.Sprintf("error on PUT %s: %s, statusCode %d", api, err, statusCode)) } return nil } diff --git a/internal/provider/security/security_login_message_resource.go b/internal/provider/security/security_login_message_resource.go index 3bacf37f..8ce203d7 100644 --- a/internal/provider/security/security_login_message_resource.go +++ b/internal/provider/security/security_login_message_resource.go @@ -26,7 +26,7 @@ var _ resource.ResourceWithImportState = &SecurityLoginMessageResource{} func NewSecurityLoginMessageResource() resource.Resource { return &SecurityLoginMessageResource{ config: connection.ResourceOrDataSourceConfig{ - Name: "security_login_message", + Name: "security_login_messages", }, } } @@ -56,7 +56,7 @@ func (r *SecurityLoginMessageResource) Metadata(ctx context.Context, req resourc func (r *SecurityLoginMessageResource) 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: "SecurityLoginMessage resource", + MarkdownDescription: "SecurityLoginMessages resource", Attributes: map[string]schema.Attribute{ "cx_profile_name": schema.StringAttribute{ From 07f54fc6e1bf43cdfd872ef4e136ef4f8f37aff7 Mon Sep 17 00:00:00 2001 From: Chuyi Ching Date: Thu, 29 Aug 2024 13:25:14 -0700 Subject: [PATCH 6/8] fix naming on acc test --- .../security_security_login_message_resource_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/provider/security/security_security_login_message_resource_test.go b/internal/provider/security/security_security_login_message_resource_test.go index cf5aec2a..7c1eb021 100644 --- a/internal/provider/security/security_security_login_message_resource_test.go +++ b/internal/provider/security/security_security_login_message_resource_test.go @@ -16,27 +16,27 @@ func TestAccSecurityLoginMessage(t *testing.T) { PreCheck: func() { ntest.TestAccPreCheck(t) }, ProtoV6ProviderFactories: ntest.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ - // Creating security_login_message test + // Creating security_login_messages test { Config: testAccSecurityLoginMessageBasicClusterConfig(), ExpectError: regexp.MustCompile("create operation is not supported"), }, // Import and read with cluster { - ResourceName: "netapp-ontap_security_login_message.example", + ResourceName: "netapp-ontap_security_login_messages.example", ImportState: true, ImportStateId: "cluster1", Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("netapp-ontap_security_login_message.example", "scope", "cluster"), + resource.TestCheckResourceAttr("netapp-ontap_security_login_messages.example", "scope", "cluster"), ), }, // Import and read with svm { - ResourceName: "netapp-ontap_security_login_message.example", + ResourceName: "netapp-ontap_security_login_messages.example", ImportState: true, ImportStateId: "svm5,cluster1", Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("netapp-ontap_security_login_message.example", "scope", "svm"), + resource.TestCheckResourceAttr("netapp-ontap_security_login_messages.example", "scope", "svm"), ), }, // Update a option cannot tested in acc test @@ -66,7 +66,7 @@ provider "netapp-ontap" { ] } -resource "netapp-ontap_security_login_message" "example" { +resource "netapp-ontap_security_login_messages" "example" { cx_profile_name = "cluster1" message = "Test cluster only \n message\n on the cluster" show_cluster_message = true From 7c97e2845fbdb65937c67e35af6831632167a29a Mon Sep 17 00:00:00 2001 From: Chuyi Ching Date: Thu, 29 Aug 2024 13:44:56 -0700 Subject: [PATCH 7/8] change the test path back to original one --- .../protocols/protocols_cifs_share_resource_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/provider/protocols/protocols_cifs_share_resource_test.go b/internal/provider/protocols/protocols_cifs_share_resource_test.go index e23a7ea3..56e8fb9f 100644 --- a/internal/provider/protocols/protocols_cifs_share_resource_test.go +++ b/internal/provider/protocols/protocols_cifs_share_resource_test.go @@ -89,7 +89,7 @@ resource "netapp-ontap_cifs_share" "example" { cx_profile_name = "clustercifs" name = "%s" svm_name = "%s" - path = "/" + path = "/acc_test_cifs_share_volume" acls = [ { "permission": "read", @@ -127,7 +127,7 @@ resource "netapp-ontap_cifs_share" "example" { cx_profile_name = "clustercifs" name = "%s" svm_name = "%s" - path = "/" + path = "/acc_test_cifs_share_volume" acls = [ { "permission": "full_control", @@ -166,7 +166,7 @@ resource "netapp-ontap_cifs_share" "example" { cx_profile_name = "clustercifs" name = "%s" svm_name = "%s" - path = "/" + path = "/acc_test_cifs_share_volume" acls = [ { "permission": "read", @@ -210,7 +210,7 @@ resource "netapp-ontap_cifs_share" "example" { cx_profile_name = "clustercifs" name = "%s" svm_name = "%s" - path = "/" + path = "/acc_test_cifs_share_volume" acls = [ { "permission": "read", From 2718dfc1dade16f23adedb3d597665e3ddbcb381 Mon Sep 17 00:00:00 2001 From: Chuyi Ching Date: Thu, 29 Aug 2024 14:05:58 -0700 Subject: [PATCH 8/8] rename resource as security_accounts --- docs/resources/security_account_resource.md | 12 ++++++------ .../provider.tf | 0 .../resource.tf | 2 +- .../variables.tf | 0 .../provider.tf | 0 .../resource.tf | 0 .../terraform.tfvars | 0 .../variables.tf | 0 .../provider/security/security_account_resource.go | 4 ++-- .../security/security_account_resource_test.go | 12 ++++++------ 10 files changed, 15 insertions(+), 15 deletions(-) rename examples/resources/{netapp-ontap_security_account => netapp-ontap_security_accounts}/provider.tf (100%) rename examples/resources/{netapp-ontap_security_account => netapp-ontap_security_accounts}/resource.tf (77%) rename examples/resources/{netapp-ontap_security_account => netapp-ontap_security_accounts}/variables.tf (100%) rename examples/resources/{netapp-ontap_security_login_message => netapp-ontap_security_login_messages}/provider.tf (100%) rename examples/resources/{netapp-ontap_security_login_message => netapp-ontap_security_login_messages}/resource.tf (100%) rename examples/resources/{netapp-ontap_security_login_message => netapp-ontap_security_login_messages}/terraform.tfvars (100%) rename examples/resources/{netapp-ontap_security_login_message => netapp-ontap_security_login_messages}/variables.tf (100%) diff --git a/docs/resources/security_account_resource.md b/docs/resources/security_account_resource.md index 396c378a..cce653d0 100644 --- a/docs/resources/security_account_resource.md +++ b/docs/resources/security_account_resource.md @@ -1,9 +1,9 @@ --- # generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "netapp-ontap_security_account Resource - terraform-provider-netapp-ontap" +page_title: "netapp-ontap_security_accounts Resource - terraform-provider-netapp-ontap" subcategory: "Security" description: |- - SecurityAccount resource + SecurityAccounts resource --- # Resource Security Account @@ -27,7 +27,7 @@ Create/Modify/Delete a ONTAP user account ## Example Usage ```terraform -resource "netapp-ontap_security_account" "security_account" { +resource "netapp-ontap_security_accounts" "security_account" { # required to know which system to interface with cx_profile_name = "cluster4" name = "carchitest" @@ -103,7 +103,7 @@ id = `name`, `cx_profile_name` For example ```shell - terraform import netapp-ontap_security_account.act_import acc_user,cluster4 + terraform import netapp-ontap_security_accounts.act_import acc_user,cluster4 ``` ### Terraform Import Block @@ -112,7 +112,7 @@ This requires Terraform 1.5 or higher, and will auto create the configuration fo First create the block ```terraform import { - to = netapp-ontap_security_account.act_import + to = netapp-ontap_security_accounts.act_import id = "acc_user,cluster4" } ``` @@ -125,7 +125,7 @@ This will generate a file called generated.tf, which will contain the configurat # __generated__ by Terraform # Please review these resources and move them into your main configuration files. # __generated__ by Terraform from "acc_user,cluster4" -resource "netapp-ontap_security_account" "act_import" { +resource "netapp-ontap_security_accounts" "act_import" { cx_profile_name = "cluster4" name = "acc_user" applications = [ diff --git a/examples/resources/netapp-ontap_security_account/provider.tf b/examples/resources/netapp-ontap_security_accounts/provider.tf similarity index 100% rename from examples/resources/netapp-ontap_security_account/provider.tf rename to examples/resources/netapp-ontap_security_accounts/provider.tf diff --git a/examples/resources/netapp-ontap_security_account/resource.tf b/examples/resources/netapp-ontap_security_accounts/resource.tf similarity index 77% rename from examples/resources/netapp-ontap_security_account/resource.tf rename to examples/resources/netapp-ontap_security_accounts/resource.tf index 6b9dffe9..611d7d1e 100644 --- a/examples/resources/netapp-ontap_security_account/resource.tf +++ b/examples/resources/netapp-ontap_security_accounts/resource.tf @@ -1,4 +1,4 @@ -resource "netapp-ontap_security_account" "security_account" { +resource "netapp-ontap_security_accounts" "security_account" { # required to know which system to interface with cx_profile_name = "cluster4" name = "carchitest" diff --git a/examples/resources/netapp-ontap_security_account/variables.tf b/examples/resources/netapp-ontap_security_accounts/variables.tf similarity index 100% rename from examples/resources/netapp-ontap_security_account/variables.tf rename to examples/resources/netapp-ontap_security_accounts/variables.tf diff --git a/examples/resources/netapp-ontap_security_login_message/provider.tf b/examples/resources/netapp-ontap_security_login_messages/provider.tf similarity index 100% rename from examples/resources/netapp-ontap_security_login_message/provider.tf rename to examples/resources/netapp-ontap_security_login_messages/provider.tf diff --git a/examples/resources/netapp-ontap_security_login_message/resource.tf b/examples/resources/netapp-ontap_security_login_messages/resource.tf similarity index 100% rename from examples/resources/netapp-ontap_security_login_message/resource.tf rename to examples/resources/netapp-ontap_security_login_messages/resource.tf diff --git a/examples/resources/netapp-ontap_security_login_message/terraform.tfvars b/examples/resources/netapp-ontap_security_login_messages/terraform.tfvars similarity index 100% rename from examples/resources/netapp-ontap_security_login_message/terraform.tfvars rename to examples/resources/netapp-ontap_security_login_messages/terraform.tfvars diff --git a/examples/resources/netapp-ontap_security_login_message/variables.tf b/examples/resources/netapp-ontap_security_login_messages/variables.tf similarity index 100% rename from examples/resources/netapp-ontap_security_login_message/variables.tf rename to examples/resources/netapp-ontap_security_login_messages/variables.tf diff --git a/internal/provider/security/security_account_resource.go b/internal/provider/security/security_account_resource.go index b7e5fad4..67ab9f97 100644 --- a/internal/provider/security/security_account_resource.go +++ b/internal/provider/security/security_account_resource.go @@ -31,7 +31,7 @@ var _ resource.ResourceWithImportState = &SecurityAccountResource{} func NewSecurityAccountResource() resource.Resource { return &SecurityAccountResource{ config: connection.ResourceOrDataSourceConfig{ - Name: "security_account", + Name: "security_accounts", }, } } @@ -82,7 +82,7 @@ func (r *SecurityAccountResource) Metadata(ctx context.Context, req resource.Met func (r *SecurityAccountResource) 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: "SecurityAccount resource", + MarkdownDescription: "SecurityAccounts resource", Attributes: map[string]schema.Attribute{ "cx_profile_name": schema.StringAttribute{ diff --git a/internal/provider/security/security_account_resource_test.go b/internal/provider/security/security_account_resource_test.go index ee306d95..98fd3935 100644 --- a/internal/provider/security/security_account_resource_test.go +++ b/internal/provider/security/security_account_resource_test.go @@ -17,24 +17,24 @@ func TestAccSecurityAccountResource(t *testing.T) { { Config: testAccSecurityAccountResourceConfig("carchitest", "password"), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("netapp-ontap_security_account.security_account", "name", "carchitest"), + resource.TestCheckResourceAttr("netapp-ontap_security_accounts.security_account", "name", "carchitest"), ), }, // Test updating a resource { Config: testAccSecurityAccountResourceConfig("carchitest", "password123"), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("netapp-ontap_security_account.security_account", "name", "carchitest"), - resource.TestCheckResourceAttr("netapp-ontap_security_account.security_account", "password", "password123"), + resource.TestCheckResourceAttr("netapp-ontap_security_accounts.security_account", "name", "carchitest"), + resource.TestCheckResourceAttr("netapp-ontap_security_accounts.security_account", "password", "password123"), ), }, // Test importing a resource { - ResourceName: "netapp-ontap_security_account.security_account", + ResourceName: "netapp-ontap_security_accounts.security_account", ImportState: true, ImportStateId: fmt.Sprintf("%s,%s", "acc_user", "cluster2"), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("netapp-ontap_security_account.security_account", "name", "acc_user"), + resource.TestCheckResourceAttr("netapp-ontap_security_accounts.security_account", "name", "acc_user"), ), }, }, @@ -62,7 +62,7 @@ provider "netapp-ontap" { ] } -resource "netapp-ontap_security_account" "security_account" { +resource "netapp-ontap_security_accounts" "security_account" { # required to know which system to interface with cx_profile_name = "cluster2" name = "%s"