From 4bf4280910ebd992f5ade42a47d232e5e40650bb Mon Sep 17 00:00:00 2001 From: dgomez04 Date: Wed, 23 Oct 2024 12:08:04 -0600 Subject: [PATCH] #3468: started moving the resource to the plugin framework, adding support for both workspace and account-level usage. --- .../pluginfw/resources/user/data_users.go | 93 +++++++++++++++++++ .../resources/user/data_users_acc_test.go | 0 .../resources/user/data_users_test.go | 0 scim/data_users.go | 3 +- 4 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 internal/providers/pluginfw/resources/user/data_users.go create mode 100644 internal/providers/pluginfw/resources/user/data_users_acc_test.go create mode 100644 internal/providers/pluginfw/resources/user/data_users_test.go diff --git a/internal/providers/pluginfw/resources/user/data_users.go b/internal/providers/pluginfw/resources/user/data_users.go new file mode 100644 index 0000000000..851cb77f53 --- /dev/null +++ b/internal/providers/pluginfw/resources/user/data_users.go @@ -0,0 +1,93 @@ +package user + +import ( + "context" + + "github.com/databricks/terraform-provider-databricks/common" + pluginfwcommon "github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/common" + "github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/tfschema" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func DataSourceUsers() datasource.DataSource { + return &UsersDataSource{} +} + +var _ datasource.DataSourceWithConfigure = &UsersDataSource{} + +type UsersDataSource struct { + Client *common.DatabricksClient +} + +type UserData struct { + Id types.String `tfsdk:"id,omitempty" tf:"computed"` + UserName types.String `tfsdk:"user_name,omitempty" tf:"computed"` + DisplayName types.String `tfsdk:"display_name,omitempty" tf:"computed"` +} + +type UsersInfo struct { + DisplayNameContains string `json:"display_name_contains,omitempty" tf:"computed"` + UserNameContains string `json:"user_name_contains,omitempty" tf:"computed"` + Users []UserData `json:"users,omitempty" tf:"computed"` // TODO: use UserData[] or []iam_tf.ListAccountUserResponse / []iam_tf.ListUserResponse? +} + +func (d *UsersDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = "databricks_users" +} + +func (d *UsersDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + attrs, blocks := tfschema.DataSourceStructToSchemaMap(UsersInfo{}, nil) + resp.Schema = schema.Schema{ + Attributes: attrs, + Blocks: blocks, + } +} + +func (d *UsersDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if d.Client == nil { + d.Client = pluginfwcommon.ConfigureDataSource(req, resp) + } +} + +// AppendDiagAndCheckErrors is a helper function that simplifies error handling by combining the appending of diagnostics and the checking of errors in a single step. +// It is particularly useful in data source and resource read operations where you want to append diagnostics and immediately determine if an error has occurred. +func AppendDiagAndCheckErrors(resp *datasource.ReadResponse, diags diag.Diagnostics) bool { + resp.Diagnostics.Append(diags...) + return resp.Diagnostics.HasError() +} + +func validateFilters(data *UsersInfo) diag.Diagnostics { + if data.DisplayNameContains != "" && data.UserNameContains != "" { + return diag.Diagnostics{diag.NewErrorDiagnostic("Invalid configuration", "Exactly one of display_name_contains or user_name_contains should be specified, not both.")} + } + return nil +} + +func (d *UsersDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var userInfo UsersInfo + + diags := req.Config.Get(ctx, &userInfo) + diags = append(diags, validateFilters(&userInfo)...) + + if AppendDiagAndCheckErrors(resp, diags) { + return + } + + if d.Client.Config.IsAccountClient() { + a, diags := d.Client.GetAccountClient() + if AppendDiagAndCheckErrors(resp, diags) { + return + } + // TODO: Add retrieval of iterator at the account level. + } else { + w, diags := d.Client.GetWorkspaceClient() + if AppendDiagAndCheckErrors(resp, diags) { + return + } + // TODO: Add retreival of iterator at the workspace level. + } + // TODO: Continue setting the datasource. +} diff --git a/internal/providers/pluginfw/resources/user/data_users_acc_test.go b/internal/providers/pluginfw/resources/user/data_users_acc_test.go new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/providers/pluginfw/resources/user/data_users_test.go b/internal/providers/pluginfw/resources/user/data_users_test.go new file mode 100644 index 0000000000..e69de29bb2 diff --git a/scim/data_users.go b/scim/data_users.go index b3fcd03782..ccd43dc6bf 100755 --- a/scim/data_users.go +++ b/scim/data_users.go @@ -4,7 +4,6 @@ import ( "context" "fmt" - "github.com/databricks/databricks-sdk-go" "github.com/databricks/databricks-sdk-go/service/iam" "github.com/databricks/terraform-provider-databricks/common" ) @@ -23,7 +22,7 @@ func DataSourceUsers() common.Resource { Users []UserInfo `json:"users,omitempty" tf:"computed"` } - return common.AccountData(func(ctx context.Context, data *DataUsers, acc *databricks.AccountClient) error { + return common.Data(func(ctx context.Context, data *DataUsers, c *common.DatabricksClient) error { listRequest := iam.ListAccountUsersRequest{ Attributes: "id,userName,displayName", }