-
Notifications
You must be signed in to change notification settings - Fork 479
Make databricks_entitlements forward-compatible with new entitlements
#4763
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 3 commits
9809299
623e7c5
a34ae43
0a82a58
894bddb
f1697cb
5fddd95
e0f3e38
38e8de9
4433bd4
2408202
c0ebac3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| package scim | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
|
|
||
| "github.com/hashicorp/terraform-plugin-log/tflog" | ||
| ) | ||
|
|
||
| type entitlements struct { | ||
| AllowClusterCreate bool `json:"allow_cluster_create,omitempty"` | ||
| AllowInstancePoolCreate bool `json:"allow_instance_pool_create,omitempty"` | ||
| DatabricksSQLAccess bool `json:"databricks_sql_access,omitempty"` | ||
| WorkspaceAccess bool `json:"workspace_access,omitempty"` | ||
| } | ||
|
|
||
| func (e entitlements) toComplexValueList() []ComplexValue { | ||
| result := []ComplexValue{} | ||
| if e.AllowClusterCreate { | ||
| result = append(result, ComplexValue{ | ||
| Value: "allow-cluster-create", | ||
| }) | ||
| } | ||
| if e.AllowInstancePoolCreate { | ||
| result = append(result, ComplexValue{ | ||
| Value: "allow-instance-pool-create", | ||
| }) | ||
| } | ||
| if e.DatabricksSQLAccess { | ||
| result = append(result, ComplexValue{ | ||
| Value: "databricks-sql-access", | ||
| }) | ||
| } | ||
| if e.WorkspaceAccess { | ||
| result = append(result, ComplexValue{ | ||
| Value: "workspace-access", | ||
| }) | ||
| } | ||
| return result | ||
| } | ||
|
|
||
| func newEntitlements(ctx context.Context, cv []ComplexValue) entitlements { | ||
| var e entitlements | ||
| for _, c := range cv { | ||
| switch c.Value { | ||
| case "allow-cluster-create": | ||
| e.AllowClusterCreate = true | ||
| case "allow-instance-pool-create": | ||
| e.AllowInstancePoolCreate = true | ||
| case "databricks-sql-access": | ||
| e.DatabricksSQLAccess = true | ||
| case "workspace-access": | ||
| e.WorkspaceAccess = true | ||
| default: | ||
| tflog.Info(ctx, fmt.Sprintf("Ignoring unknown entitlement: %s", c.Value)) | ||
| } | ||
| } | ||
| return e | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -9,82 +9,86 @@ import ( | |||||
| "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
| ) | ||||||
|
|
||||||
| type entitlementsResource struct { | ||||||
| entitlements | ||||||
| GroupId string `json:"group_id,omitempty" tf:"force_new"` | ||||||
| UserId string `json:"user_id,omitempty" tf:"force_new"` | ||||||
| SpnId string `json:"service_principal_id,omitempty" tf:"force_new"` | ||||||
| } | ||||||
|
|
||||||
| // ResourceGroup manages user groups | ||||||
| func ResourceEntitlements() common.Resource { | ||||||
| type entity struct { | ||||||
| GroupId string `json:"group_id,omitempty" tf:"force_new"` | ||||||
| UserId string `json:"user_id,omitempty" tf:"force_new"` | ||||||
| SpnId string `json:"service_principal_id,omitempty" tf:"force_new"` | ||||||
| } | ||||||
| entitlementSchema := common.StructToSchema(entity{}, | ||||||
| entitlementSchema := common.StructToSchema(entitlementsResource{}, | ||||||
| func(m map[string]*schema.Schema) map[string]*schema.Schema { | ||||||
| addEntitlementsToSchema(m) | ||||||
| alof := []string{"group_id", "user_id", "service_principal_id"} | ||||||
| for _, field := range alof { | ||||||
| m[field].AtLeastOneOf = alof | ||||||
| } | ||||||
| return m | ||||||
| }) | ||||||
| addEntitlementsToSchema(entitlementSchema) | ||||||
| return common.Resource{ | ||||||
| Create: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error { | ||||||
| if c.Config.IsAccountClient() { | ||||||
| return fmt.Errorf("entitlements can only be managed with a provider configured at the workspace-level") | ||||||
| } | ||||||
| err := patchEntitlements(ctx, d, c, "replace") | ||||||
| var e entitlementsResource | ||||||
| common.DataToStructPointer(d, entitlementSchema, &e) | ||||||
| err := patchEntitlements(ctx, e, c, "replace") | ||||||
| if err != nil { | ||||||
| return err | ||||||
| } | ||||||
| d.SetId(getId(d)) | ||||||
| d.SetId(getId(e)) | ||||||
| return nil | ||||||
| }, | ||||||
| Read: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error { | ||||||
| split := strings.SplitN(d.Id(), "/", 2) | ||||||
| if len(split) != 2 { | ||||||
| return fmt.Errorf("ID must be two elements: %s", d.Id()) | ||||||
| } | ||||||
| var entitlements entitlementsResource | ||||||
| switch strings.ToLower(split[0]) { | ||||||
| case "group": | ||||||
| group, err := NewGroupsAPI(ctx, c).Read(split[1], "entitlements") | ||||||
| if err != nil { | ||||||
| return err | ||||||
| } | ||||||
| d.Set("group_id", split[1]) | ||||||
| group.Entitlements.generateEmpty(d) | ||||||
| return group.Entitlements.readIntoData(d) | ||||||
| entitlements.GroupId = split[1] | ||||||
| entitlements.entitlements = newEntitlements(ctx, group.Entitlements) | ||||||
| case "user": | ||||||
| user, err := NewUsersAPI(ctx, c).Read(split[1], "entitlements") | ||||||
| if err != nil { | ||||||
| return err | ||||||
| } | ||||||
| d.Set("user_id", split[1]) | ||||||
| user.Entitlements.generateEmpty(d) | ||||||
| return user.Entitlements.readIntoData(d) | ||||||
| entitlements.UserId = split[1] | ||||||
| entitlements.entitlements = newEntitlements(ctx, user.Entitlements) | ||||||
| case "spn": | ||||||
| spn, err := NewServicePrincipalsAPI(ctx, c).Read(split[1], "entitlements") | ||||||
| if err != nil { | ||||||
| return err | ||||||
| } | ||||||
| d.Set("service_principal_id", split[1]) | ||||||
| spn.Entitlements.generateEmpty(d) | ||||||
| return spn.Entitlements.readIntoData(d) | ||||||
| entitlements.SpnId = split[1] | ||||||
| entitlements.entitlements = newEntitlements(ctx, spn.Entitlements) | ||||||
| } | ||||||
| return nil | ||||||
| return common.StructToData(entitlements, entitlementSchema, d) | ||||||
| }, | ||||||
| Update: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error { | ||||||
| return patchEntitlements(ctx, d, c, "replace") | ||||||
| var e entitlementsResource | ||||||
| common.DataToStructPointer(d, entitlementSchema, &e) | ||||||
| return patchEntitlements(ctx, e, c, "replace") | ||||||
| }, | ||||||
| Delete: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error { | ||||||
| return patchEntitlements(ctx, d, c, "remove") | ||||||
| var e entitlementsResource | ||||||
| common.DataToStructPointer(d, entitlementSchema, &e) | ||||||
| return patchEntitlements(ctx, e, c, "remove") | ||||||
| }, | ||||||
| Schema: entitlementSchema, | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| func getId(d *schema.ResourceData) string { | ||||||
| groupId := d.Get("group_id").(string) | ||||||
| userId := d.Get("user_id").(string) | ||||||
| spnId := d.Get("service_principal_id").(string) | ||||||
| func getId(e entitlementsResource) string { | ||||||
| groupId := e.GroupId | ||||||
| userId := e.UserId | ||||||
| spnId := e.SpnId | ||||||
| if groupId != "" { | ||||||
| return "group/" + groupId | ||||||
| } | ||||||
|
|
@@ -97,12 +101,12 @@ func getId(d *schema.ResourceData) string { | |||||
| return "" | ||||||
| } | ||||||
|
|
||||||
| func patchEntitlements(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient, op string) error { | ||||||
| groupId := d.Get("group_id").(string) | ||||||
| userId := d.Get("user_id").(string) | ||||||
| spnId := d.Get("service_principal_id").(string) | ||||||
| func patchEntitlements(ctx context.Context, e entitlementsResource, c *common.DatabricksClient, op string) error { | ||||||
| groupId := e.GroupId | ||||||
| userId := e.UserId | ||||||
| spnId := e.SpnId | ||||||
| noEntitlementMessage := "invalidPath No such attribute with the name : entitlements in the current resource" | ||||||
| entitlements := readEntitlementsFromData(d) | ||||||
| entitlements := e.toComplexValueList() | ||||||
|
||||||
| entitlements := e.toComplexValueList() | |
| entitlements := e.entitlements.toComplexValueList() |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -10,37 +10,32 @@ import ( | |||||
| "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" | ||||||
| ) | ||||||
|
|
||||||
| type groupResource struct { | ||||||
| entitlements | ||||||
| DisplayName string `json:"display_name"` | ||||||
| ExternalID string `json:"external_id,omitempty" tf:"force_new,suppress_diff"` | ||||||
| URL string `json:"url,omitempty" tf:"computed"` | ||||||
| AclPrincipalID string `json:"acl_principal_id,omitempty" tf:"computed"` | ||||||
| Force bool `json:"force,omitempty"` | ||||||
| } | ||||||
|
|
||||||
| // ResourceGroup manages user groups | ||||||
| func ResourceGroup() common.Resource { | ||||||
| type entity struct { | ||||||
| DisplayName string `json:"display_name"` | ||||||
| ExternalID string `json:"external_id,omitempty" tf:"force_new,suppress_diff"` | ||||||
| URL string `json:"url,omitempty" tf:"computed"` | ||||||
| } | ||||||
| groupSchema := common.StructToSchema(entity{}, | ||||||
| groupSchema := common.StructToSchema(groupResource{}, | ||||||
| func(m map[string]*schema.Schema) map[string]*schema.Schema { | ||||||
| addEntitlementsToSchema(m) | ||||||
| // https://github.com/databricks/terraform-provider-databricks/issues/1089 | ||||||
| m["display_name"].ValidateDiagFunc = validation.ToDiagFunc( | ||||||
| validation.StringNotInSlice([]string{"users", "admins"}, false)) | ||||||
| m["force"] = &schema.Schema{ | ||||||
| Type: schema.TypeBool, | ||||||
| Optional: true, | ||||||
| } | ||||||
| m["acl_principal_id"] = &schema.Schema{ | ||||||
| Type: schema.TypeString, | ||||||
| Optional: true, | ||||||
| Computed: true, | ||||||
| } | ||||||
| return m | ||||||
| }) | ||||||
| addEntitlementsToSchema(groupSchema) | ||||||
| return common.Resource{ | ||||||
| Create: func(ctx context.Context, d *schema.ResourceData, c *common.DatabricksClient) error { | ||||||
| var groupResource groupResource | ||||||
| common.DataToStructPointer(d, groupSchema, &groupResource) | ||||||
| g := Group{ | ||||||
| DisplayName: d.Get("display_name").(string), | ||||||
| Entitlements: readEntitlementsFromData(d), | ||||||
| ExternalID: d.Get("external_id").(string), | ||||||
| DisplayName: groupResource.DisplayName, | ||||||
| Entitlements: groupResource.toComplexValueList(), | ||||||
|
||||||
| Entitlements: groupResource.toComplexValueList(), | |
| Entitlements: groupResource.entitlements.toComplexValueList(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should it be warning?