diff --git a/CHANGELOG.md b/CHANGELOG.md index d38eec7a..e02f8468 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## 1.1.0 () +FEATURES: +* **New Data Source:** `ontap_protocols_cifs_local_user_data_source` ([#55](https://github.com/NetApp/terraform-provider-netapp-ontap/issues/55)) +* **New Data Source:** `ontap_protocols_cifs_local_users_data_source` ([#55](https://github.com/NetApp/terraform-provider-netapp-ontap/issues/55)) + ENHANCEMENTS: * **netapp-ontap_protocols_nfs_export_policy_resource**: Add support for import ([#34](https://github.com/NetApp/terraform-provider-netapp-ontap/issues/34)) diff --git a/examples/data-sources/netapp-ontap_protocols_cifs_local_user/data-source.tf b/examples/data-sources/netapp-ontap_protocols_cifs_local_user/data-source.tf new file mode 100644 index 00000000..011087d1 --- /dev/null +++ b/examples/data-sources/netapp-ontap_protocols_cifs_local_user/data-source.tf @@ -0,0 +1,6 @@ +data "netapp-ontap_protocols_cifs_local_user_data_source" "protocols_cifs_local_user" { + # required to know which system to interface with + cx_profile_name = "cluster4" + svm_name = "svm1" + name = "testme" +} diff --git a/examples/data-sources/netapp-ontap_protocols_cifs_local_user/provider.tf b/examples/data-sources/netapp-ontap_protocols_cifs_local_user/provider.tf new file mode 120000 index 00000000..c6b7138f --- /dev/null +++ b/examples/data-sources/netapp-ontap_protocols_cifs_local_user/provider.tf @@ -0,0 +1 @@ +../../provider/provider.tf \ No newline at end of file diff --git a/examples/data-sources/netapp-ontap_protocols_cifs_local_user/terraform.tfvars b/examples/data-sources/netapp-ontap_protocols_cifs_local_user/terraform.tfvars new file mode 120000 index 00000000..8d9d1c96 --- /dev/null +++ b/examples/data-sources/netapp-ontap_protocols_cifs_local_user/terraform.tfvars @@ -0,0 +1 @@ +../../provider/terraform.tfvars \ No newline at end of file diff --git a/examples/data-sources/netapp-ontap_protocols_cifs_local_user/variables.tf b/examples/data-sources/netapp-ontap_protocols_cifs_local_user/variables.tf new file mode 120000 index 00000000..395ce618 --- /dev/null +++ b/examples/data-sources/netapp-ontap_protocols_cifs_local_user/variables.tf @@ -0,0 +1 @@ +../../provider/variables.tf \ No newline at end of file diff --git a/examples/data-sources/netapp-ontap_protocols_cifs_local_users/data-source.tf b/examples/data-sources/netapp-ontap_protocols_cifs_local_users/data-source.tf new file mode 100644 index 00000000..2531645d --- /dev/null +++ b/examples/data-sources/netapp-ontap_protocols_cifs_local_users/data-source.tf @@ -0,0 +1,8 @@ +data "netapp-ontap_protocols_cifs_local_users_data_source" "protocols_cifs_local_users" { + # required to know which system to interface with + cx_profile_name = "cluster4" + filter = { + name = "user1" + svm_name = "svm*" + } +} diff --git a/examples/data-sources/netapp-ontap_protocols_cifs_local_users/provider.tf b/examples/data-sources/netapp-ontap_protocols_cifs_local_users/provider.tf new file mode 120000 index 00000000..c6b7138f --- /dev/null +++ b/examples/data-sources/netapp-ontap_protocols_cifs_local_users/provider.tf @@ -0,0 +1 @@ +../../provider/provider.tf \ No newline at end of file diff --git a/examples/data-sources/netapp-ontap_protocols_cifs_local_users/terraform.tfvars b/examples/data-sources/netapp-ontap_protocols_cifs_local_users/terraform.tfvars new file mode 120000 index 00000000..8d9d1c96 --- /dev/null +++ b/examples/data-sources/netapp-ontap_protocols_cifs_local_users/terraform.tfvars @@ -0,0 +1 @@ +../../provider/terraform.tfvars \ No newline at end of file diff --git a/examples/data-sources/netapp-ontap_protocols_cifs_local_users/variables.tf b/examples/data-sources/netapp-ontap_protocols_cifs_local_users/variables.tf new file mode 120000 index 00000000..395ce618 --- /dev/null +++ b/examples/data-sources/netapp-ontap_protocols_cifs_local_users/variables.tf @@ -0,0 +1 @@ +../../provider/variables.tf \ No newline at end of file diff --git a/internal/interfaces/protocols_cifs_local_user.go b/internal/interfaces/protocols_cifs_local_user.go new file mode 100644 index 00000000..57ea6888 --- /dev/null +++ b/internal/interfaces/protocols_cifs_local_user.go @@ -0,0 +1,136 @@ +package interfaces + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/mitchellh/mapstructure" + "github.com/netapp/terraform-provider-netapp-ontap/internal/restclient" + "github.com/netapp/terraform-provider-netapp-ontap/internal/utils" +) + +// TODO: +// copy this file to match you data source (should match internal/interfaces/protocols_cifs_local_user.go) +// replace CifsLocalUser with the name of the resource, following go conventions, eg IPInterface +// replace protocols_cifs_local_user with the name of the resource, for logging purposes, eg ip_interface +// replace api_url with API, eg ip/interfaces +// delete these 5 lines + +// CifsLocalUserGetDataModelONTAP describes the GET record data model using go types for mapping. +type CifsLocalUserGetDataModelONTAP struct { + Name string `mapstructure:"name"` + SID string `mapstructure:"sid"` + SVM svm `mapstructure:"svm"` + FullName string `mapstructure:"full_name"` + Description string `mapstructure:"description"` + Membership []membership `mapstructure:"membership"` + AccountDisabled bool `mapstructure:"account_disabled"` +} + +// Membership describes the membership data model using go types for mapping. +type membership struct { + Name string `mapstructure:"name"` +} + +// CifsLocalUserDataSourceFilterModel describes the data source data model for queries. +type CifsLocalUserDataSourceFilterModel struct { + Name string `mapstructure:"name"` + SVMName string `mapstructure:"svm.name"` +} + +// CifsLocalUserResourceBodyDataModelONTAP describes the body data model using go types for mapping. +type CifsLocalUserResourceBodyDataModelONTAP struct { + Name string `mapstructure:"name"` + SVM svm `mapstructure:"svm"` +} + +// GetCifsLocalUser to get protocols_cifs_local_user info +func GetCifsLocalUserByName(errorHandler *utils.ErrorHandler, r restclient.RestClient, name string, svmName string) (*CifsLocalUserGetDataModelONTAP, error) { + api := "protocols/cifs/local-users" + query := r.NewQuery() + query.Set("name", name) + query.Set("svm.name", svmName) + + query.Fields([]string{"name", "svm.name", "full_name", "description", "membership", "account_disabled"}) + statusCode, response, err := r.GetNilOrOneRecord(api, query, nil) + if err == nil && response == nil { + err = fmt.Errorf("no response for GET %s", api) + } + if err != nil { + return nil, errorHandler.MakeAndReportError("error reading protocols_cifs_local_user info", fmt.Sprintf("error on GET %s: %s, statusCode %d", api, err, statusCode)) + } + + var dataONTAP CifsLocalUserGetDataModelONTAP + if err := mapstructure.Decode(response, &dataONTAP); err != nil { + return nil, errorHandler.MakeAndReportError(fmt.Sprintf("failed to decode response from GET %s", api), + fmt.Sprintf("error: %s, statusCode %d, response %#v", err, statusCode, response)) + } + tflog.Debug(errorHandler.Ctx, fmt.Sprintf("Read protocols_cifs_local_user data source: %#v", dataONTAP)) + return &dataONTAP, nil +} + +// GetCifsLocalUsers to get protocols_cifs_local_user info for all resources matching a filter +func GetCifsLocalUsers(errorHandler *utils.ErrorHandler, r restclient.RestClient, filter *CifsLocalUserDataSourceFilterModel) ([]CifsLocalUserGetDataModelONTAP, error) { + api := "protocols/cifs/local-users" + query := r.NewQuery() + query.Fields([]string{"name", "svm.name", "full_name", "description", "membership", "account_disabled"}) + + if filter != nil { + var filterMap map[string]interface{} + if err := mapstructure.Decode(filter, &filterMap); err != nil { + return nil, errorHandler.MakeAndReportError("error encoding protocols_cifs_local_users filter info", fmt.Sprintf("error on filter %#v: %s", filter, err)) + } + query.SetValues(filterMap) + } + statusCode, response, err := r.GetZeroOrMoreRecords(api, query, nil) + if err == nil && response == nil { + err = fmt.Errorf("no response for GET %s", api) + } + if err != nil { + return nil, errorHandler.MakeAndReportError("error reading protocols_cifs_local_users info", fmt.Sprintf("error on GET %s: %s, statusCode %d", api, err, statusCode)) + } + + var dataONTAP []CifsLocalUserGetDataModelONTAP + for _, info := range response { + var record CifsLocalUserGetDataModelONTAP + if err := mapstructure.Decode(info, &record); err != nil { + return nil, errorHandler.MakeAndReportError(fmt.Sprintf("failed to decode response from GET %s", api), + fmt.Sprintf("error: %s, statusCode %d, info %#v", err, statusCode, info)) + } + dataONTAP = append(dataONTAP, record) + } + tflog.Debug(errorHandler.Ctx, fmt.Sprintf("Read protocols_cifs_local_users data source: %#v", dataONTAP)) + return dataONTAP, nil +} + +// CreateCifsLocalUser to create protocols_cifs_local_user +func CreateCifsLocalUser(errorHandler *utils.ErrorHandler, r restclient.RestClient, body CifsLocalUserResourceBodyDataModelONTAP) (*CifsLocalUserGetDataModelONTAP, error) { + api := "protocols/cifs/local-users" + var bodyMap map[string]interface{} + if err := mapstructure.Decode(body, &bodyMap); err != nil { + return nil, errorHandler.MakeAndReportError("error encoding protocols_cifs_local_user body", fmt.Sprintf("error on encoding %s body: %s, body: %#v", api, err, 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 protocols_cifs_local_user", fmt.Sprintf("error on POST %s: %s, statusCode %d", api, err, statusCode)) + } + + var dataONTAP CifsLocalUserGetDataModelONTAP + if err := mapstructure.Decode(response.Records[0], &dataONTAP); err != nil { + return nil, errorHandler.MakeAndReportError("error decoding protocols_cifs_local_user info", fmt.Sprintf("error on decode storage/protocols_cifs_local_users info: %s, statusCode %d, response %#v", err, statusCode, response)) + } + tflog.Debug(errorHandler.Ctx, fmt.Sprintf("Create protocols_cifs_local_user source - udata: %#v", dataONTAP)) + return &dataONTAP, nil +} + +// DeleteCifsLocalUser to delete protocols_cifs_local_user +func DeleteCifsLocalUser(errorHandler *utils.ErrorHandler, r restclient.RestClient, uuid string) error { + api := "protocols/cifs/local-users" + statusCode, _, err := r.CallDeleteMethod(api+"/"+uuid, nil, nil) + if err != nil { + return errorHandler.MakeAndReportError("error deleting protocols_cifs_local_user", fmt.Sprintf("error on DELETE %s: %s, statusCode %d", api, err, statusCode)) + } + return nil +} diff --git a/internal/provider/protocols_cifs_local_user_data_source.go b/internal/provider/protocols_cifs_local_user_data_source.go new file mode 100644 index 00000000..b131415b --- /dev/null +++ b/internal/provider/protocols_cifs_local_user_data_source.go @@ -0,0 +1,162 @@ +package provider + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "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 _ datasource.DataSource = &CifsLocalUserDataSource{} + +// NewCifsLocalUserDataSource is a helper function to simplify the provider implementation. +func NewCifsLocalUserDataSource() datasource.DataSource { + return &CifsLocalUserDataSource{ + config: resourceOrDataSourceConfig{ + name: "protocols_cifs_local_user_data_source", + }, + } +} + +// CifsLocalUserDataSource defines the data source implementation. +type CifsLocalUserDataSource struct { + config resourceOrDataSourceConfig +} + +// CifsLocalUserDataSourceModel describes the data source data model. +type CifsLocalUserDataSourceModel struct { + CxProfileName types.String `tfsdk:"cx_profile_name"` + Name types.String `tfsdk:"name"` + SVMName types.String `tfsdk:"svm_name"` + FullName types.String `tfsdk:"full_name"` + Description types.String `tfsdk:"description"` + Membership []Membership `tfsdk:"membership"` + AccountDisabled types.Bool `tfsdk:"account_disabled"` + ID types.String `tfsdk:"id"` +} + +// Membership describes the membership data model. +type Membership struct { + Name types.String `tfsdk:"name"` +} + +// Metadata returns the data source type name. +func (d *CifsLocalUserDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_" + d.config.name +} + +// Schema defines the schema for the data source. +func (d *CifsLocalUserDataSource) 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: "CifsLocalUser data source", + + Attributes: map[string]schema.Attribute{ + "cx_profile_name": schema.StringAttribute{ + MarkdownDescription: "Connection profile name", + Required: true, + }, + "name": schema.StringAttribute{ + MarkdownDescription: "CifsLocalUser name", + Required: true, + }, + "svm_name": schema.StringAttribute{ + MarkdownDescription: "IPInterface svm name", + Required: true, + }, + "full_name": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "CifsLocalUser full name", + }, + "description": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "CifsLocalUser description", + }, + "membership": schema.ListNestedAttribute{ + Computed: true, + MarkdownDescription: "CifsLocalUser membership", + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "CifsLocalUser membership name", + }, + }, + }, + }, + "account_disabled": schema.BoolAttribute{ + Computed: true, + MarkdownDescription: "CifsLocalUser account disabled", + }, + "id": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "CifsLocalUser id", + }, + }, + } +} + +// Configure adds the provider configured client to the data source. +func (d *CifsLocalUserDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + config, ok := req.ProviderData.(Config) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected Config, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + } + d.config.providerConfig = config +} + +// Read refreshes the Terraform state with the latest data. +func (d *CifsLocalUserDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data CifsLocalUserDataSourceModel + + // Read Terraform configuration data into the model + resp.Diagnostics.Append(req.Config.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 := getRestClient(errorHandler, d.config, data.CxProfileName) + if err != nil { + // error reporting done inside NewClient + return + } + + restInfo, err := interfaces.GetCifsLocalUserByName(errorHandler, *client, data.Name.ValueString(), data.SVMName.ValueString()) + if err != nil { + // error reporting done inside GetCifsLocalUser + return + } + data.ID = types.StringValue(restInfo.SID) + data.SVMName = types.StringValue(restInfo.SVM.Name) + data.Name = types.StringValue(restInfo.Name) + data.FullName = types.StringValue(restInfo.FullName) + data.Description = types.StringValue(restInfo.Description) + data.AccountDisabled = types.BoolValue(restInfo.AccountDisabled) + data.Membership = make([]Membership, len(restInfo.Membership)) + for i, m := range restInfo.Membership { + data.Membership[i].Name = types.StringValue(m.Name) + } + + // Write logs using the tflog package + // Documentation: https://terraform.io/plugin/log + tflog.Debug(ctx, fmt.Sprintf("read a data source: %#v", data)) + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} diff --git a/internal/provider/protocols_cifs_local_users_data_source.go b/internal/provider/protocols_cifs_local_users_data_source.go new file mode 100644 index 00000000..38ce871e --- /dev/null +++ b/internal/provider/protocols_cifs_local_users_data_source.go @@ -0,0 +1,197 @@ +package provider + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "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 _ datasource.DataSource = &CifsLocalUsersDataSource{} + +// NewCifsLocalUsersDataSource is a helper function to simplify the provider implementation. +func NewCifsLocalUsersDataSource() datasource.DataSource { + return &CifsLocalUsersDataSource{ + config: resourceOrDataSourceConfig{ + name: "protocols_cifs_local_users_data_source", + }, + } +} + +// CifsLocalUsersDataSource defines the data source implementation. +type CifsLocalUsersDataSource struct { + config resourceOrDataSourceConfig +} + +// CifsLocalUserDataSourceFilterModel describes the data source data model. +type CifsLocalUserDataSourceFilterModel struct { + Name types.String `tfsdk:"name"` + SVMName types.String `tfsdk:"svm_name"` +} + +type CifsLocalUsersDataSourceModel struct { + CxProfileName types.String `tfsdk:"cx_profile_name"` + CifsLocalUsers []CifsLocalUserDataSourceModel `tfsdk:"protocols_cifs_local_users"` + Filter *CifsLocalUserDataSourceFilterModel `tfsdk:"filter"` +} + +// Metadata returns the data source type name. +func (d *CifsLocalUsersDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_" + d.config.name +} + +// Schema defines the schema for the data source. +func (d *CifsLocalUsersDataSource) 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: "CifsLocalUsers data source", + + Attributes: map[string]schema.Attribute{ + "cx_profile_name": schema.StringAttribute{ + MarkdownDescription: "Connection profile name", + Required: true, + }, + "filter": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + MarkdownDescription: "CifsLocalUser name", + Optional: true, + }, + "svm_name": schema.StringAttribute{ + MarkdownDescription: "CifsLocalUser svm name", + Optional: true, + }, + }, + Optional: true, + }, + "protocols_cifs_local_users": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "cx_profile_name": schema.StringAttribute{ + MarkdownDescription: "Connection profile name", + Required: true, + }, + "name": schema.StringAttribute{ + MarkdownDescription: "CifsLocalUser name", + Required: true, + }, + "svm_name": schema.StringAttribute{ + MarkdownDescription: "CifsLocalUser svm name", + Computed: true, + }, + "full_name": schema.StringAttribute{ + MarkdownDescription: "CifsLocalUser full name", + Computed: true, + }, + "description": schema.StringAttribute{ + MarkdownDescription: "CifsLocalUser description", + Computed: true, + }, + "membership": schema.ListNestedAttribute{ + Computed: true, + MarkdownDescription: "CifsLocalUser membership", + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "CifsLocalUser membership name", + }, + }, + }, + }, + "account_disabled": schema.BoolAttribute{ + Computed: true, + MarkdownDescription: "CifsLocalUser account disabled", + }, + "id": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "CifsLocalUser id", + }, + }, + }, + Computed: true, + MarkdownDescription: "Protocols CIFS local users", + }, + }, + } +} + +// Configure adds the provider configured client to the data source. +func (d *CifsLocalUsersDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + config, ok := req.ProviderData.(Config) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected Config, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + } + d.config.providerConfig = config +} + +// Read refreshes the Terraform state with the latest data. +func (d *CifsLocalUsersDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data CifsLocalUsersDataSourceModel + + // Read Terraform configuration data into the model + resp.Diagnostics.Append(req.Config.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 := getRestClient(errorHandler, d.config, data.CxProfileName) + if err != nil { + // error reporting done inside NewClient + return + } + + var filter *interfaces.CifsLocalUserDataSourceFilterModel = nil + if data.Filter != nil { + filter = &interfaces.CifsLocalUserDataSourceFilterModel{ + Name: data.Filter.Name.ValueString(), + SVMName: data.Filter.SVMName.ValueString(), + } + } + restInfo, err := interfaces.GetCifsLocalUsers(errorHandler, *client, filter) + if err != nil { + // error reporting done inside GetCifsLocalUsers + return + } + + data.CifsLocalUsers = make([]CifsLocalUserDataSourceModel, len(restInfo)) + for index, record := range restInfo { + var membership = make([]Membership, len(record.Membership)) + for i, v := range record.Membership { + membership[i].Name = types.StringValue(v.Name) + } + data.CifsLocalUsers[index] = CifsLocalUserDataSourceModel{ + CxProfileName: types.String(data.CxProfileName), + Name: types.StringValue(record.Name), + SVMName: types.StringValue(record.SVM.Name), + FullName: types.StringValue(record.FullName), + Description: types.StringValue(record.Description), + AccountDisabled: types.BoolValue(record.AccountDisabled), + ID: types.StringValue(record.SID), + Membership: membership, + } + } + + // Write logs using the tflog package + // Documentation: https://terraform.io/plugin/log + tflog.Debug(ctx, fmt.Sprintf("read a data source: %#v", data)) + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index e50ddf98..cb103807 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -164,6 +164,8 @@ func (p *ONTAPProvider) Resources(ctx context.Context) []func() resource.Resourc // DataSources defines the provider's data sources. func (p *ONTAPProvider) DataSources(ctx context.Context) []func() datasource.DataSource { return []func() datasource.DataSource{ + NewCifsLocalUserDataSource, + NewCifsLocalUsersDataSource, NewClusterDataSource, NewClusterLicensingLicenseDataSource, NewClusterLicensingLicensesDataSource,