[Fix] Refactor databricks_permissions and allow the current user to set their own permissions#3956
[Fix] Refactor databricks_permissions and allow the current user to set their own permissions#3956
databricks_permissions and allow the current user to set their own permissions#3956Conversation
| }.ExpectError(t, "permission_level WHATEVER is not supported with cluster_id objects") | ||
| } | ||
|
|
||
| func TestResourcePermissionsCustomizeDiff_ErrorOnPermissionsDecreate(t *testing.T) { |
There was a problem hiding this comment.
This behavior is changed in this PR: users are allowed to change their permissions as long as they maintain management-level permissions.
| { | ||
| UserName: TestingAdminUser, | ||
| PermissionLevel: "IS_OWNER", | ||
| PermissionLevel: "CAN_MANAGE", |
There was a problem hiding this comment.
Order of permissions won't affect the behavior in the API.
tanmay-db
left a comment
There was a problem hiding this comment.
LGTM, had some comments.
| } | ||
|
|
||
| // safePutWithOwner is a workaround for the limitation where warehouse without owners cannot have IS_OWNER set | ||
| func (a PermissionsAPI) safePutWithOwner(objectID string, objectACL AccessControlChangeList, originalAcl []AccessControlChange) error { |
There was a problem hiding this comment.
Is this something we should also have in Go SDK and hence might be better to move it there?
There was a problem hiding this comment.
TBH I don't think it really belongs in the Go SDK. I would actually consider this more along the lines of an API issue for the permissions API for warehouses. This may not even be needed anymore now that warehouses and other SQL objects are using the global permissions API endpoints, but I need to test it out.
| // Delete gracefully removes permissions of non-admin users. After this operation, the object is managed | ||
| // by the current user and admin group. If the resource has IS_OWNER permissions, they are reset to the | ||
| // object creator, if it can be determined. | ||
| func (a PermissionsAPI) Delete(objectID string, mapping resourcePermissions) error { |
There was a problem hiding this comment.
Same for this, if true -- we could move the whole PermissionsAPI there. Currently, are SDK users expected to take care of this on their own?
There was a problem hiding this comment.
Delete permissions are fairly Terraform-specific since they define the meaning of "removing a databricks_permissions resource." Generally speaking, I would like to see more evidence for reusability of such a method before adding it to the SDK, especially when there are other methods that provide equivalent power.
permissions/acl_customizers.go
Outdated
| } | ||
| } | ||
|
|
||
| // Whether the object requires explicit manage permissions for the calling user if not set. |
There was a problem hiding this comment.
Thanks for the comments, easy to get context about this.
permissions/acl_customizers.go
Outdated
| filteredAcl = append(filteredAcl, a) | ||
| } | ||
| } | ||
| acl.AccessControlList = filteredAcl |
There was a problem hiding this comment.
We are modifying the input and returning that, I think if we want to modify the input then returning it is redundant (since it's already passed by reference) and if not (which is more safer since we don't modify the input acl which preserves the information about admins group (if needed)) we could return a new acl.
There was a problem hiding this comment.
Also since we are always returning nil as error in current implementation -- should we remove returning it / add error pathway?
There was a problem hiding this comment.
Good suggestion. I can change this method to return a new ObjectPermissions instance and not modify the original one.
There was a problem hiding this comment.
We could theoretically get rid of the error pathway, as it isn't used now, but I've kept it for symmetry. I suppose we can add it later if we need to add customizations in the future which could fail.
nkvuong
left a comment
There was a problem hiding this comment.
just a few minor comments, I will run a few test locally as well to confirm
### New Features and Improvements * Add `databricks_budget` resource ([#3955](#3955)). * Add `databricks_mlflow_models` data source ([#3874](#3874)). * Add computed attribute `table_serving_url` to `databricks_online_table` ([#4048](#4048)). * Add support for Identity Column in `databricks_sql_table` ([#4035](#4035)). ### Bug Fixes * Fix Permissions Dashboard Test ([#4071](#4071)). * Ignore presence or absence of `/Workspace` prefix for dashboard resource ([#4061](#4061)). * Refactor `databricks_permissions` and allow the current user to set their own permissions ([#3956](#3956)). * Set ID for online table resource if creation succeeds but it isn't available yet ([#4072](#4072)). ### Documentation * Add guide for OIDC authentication ([#4016](#4016)). * Correctly use native markdown callouts supported by TF Registry ([#4073](#4073)). * Fixing links to `databricks_service_principal` in TF guides ([#4020](#4020)). ### Internal Changes * Bump Go SDK to latest and generate TF structs ([#4062](#4062)). * Skip Budget tests on GCP ([#4070](#4070)). * Update to latest OpenAPI spec and bump Go SDK ([#4069](#4069)).
### New Features and Improvements * Add `databricks_budget` resource ([#3955](#3955)). * Add `databricks_mlflow_models` data source ([#3874](#3874)). * Add computed attribute `table_serving_url` to `databricks_online_table` ([#4048](#4048)). * Add support for Identity Column in `databricks_sql_table` ([#4035](#4035)). ### Bug Fixes * Fix Permissions Dashboard Test ([#4071](#4071)). * Ignore presence or absence of `/Workspace` prefix for dashboard resource ([#4061](#4061)). * Refactor `databricks_permissions` and allow the current user to set their own permissions ([#3956](#3956)). * Set ID for online table resource if creation succeeds but it isn't available yet ([#4072](#4072)). ### Documentation * Add guide for OIDC authentication ([#4016](#4016)). * Correctly use native markdown callouts supported by TF Registry ([#4073](#4073)). * Fixing links to `databricks_service_principal` in TF guides ([#4020](#4020)). ### Internal Changes * Bump Go SDK to latest and generate TF structs ([#4062](#4062)). * Skip Budget tests on GCP ([#4070](#4070)). * Update to latest OpenAPI spec and bump Go SDK ([#4069](#4069)).
### New Features and Improvements * Add `databricks_budget` resource ([#3955](#3955)). * Add `databricks_mlflow_models` data source ([#3874](#3874)). * Add computed attribute `table_serving_url` to `databricks_online_table` ([#4048](#4048)). * Add support for Identity Column in `databricks_sql_table` ([#4035](#4035)). ### Bug Fixes * Add Sufficient Network Privileges to the Databricks Default Cross Account Policy ([#4027](#4027)) * Ignore presence or absence of `/Workspace` prefix for dashboard resource ([#4061](#4061)). * Refactor `databricks_permissions` and allow the current user to set their own permissions ([#3956](#3956)). * Set ID for online table resource if creation succeeds but it isn't available yet ([#4072](#4072)). ### Documentation * Update CONTRIBUTING guide for plugin framework resources ([#4078](#4078)) * Add guide for OIDC authentication ([#4016](#4016)). * Correctly use native markdown callouts supported by TF Registry ([#4073](#4073)). * Fixing links to `databricks_service_principal` in TF guides ([#4020](#4020)). ### Internal Changes * Fix Permissions Dashboard Test ([#4071](#4071)). * Bump Go SDK to latest and generate TF structs ([#4062](#4062)). * Skip Budget tests on GCP ([#4070](#4070)). * Update to latest OpenAPI spec and bump Go SDK ([#4069](#4069)).
|
I suspect this change has introduced a regression. See #4143. |
…with `/warehouses/...` IDs (#4158) ## Changes #4143 reported a regression to the `databricks_permissions` resource caused by #3956. Normally, the ID for this resource when configured for a SQL warehouse is `/sql/warehouses/<ID>`. However, it seems like at some point in the past, some users may have had an ID of `/warehouses/<ID>`. It's possible that importing this resource worked like this: when calling the permissions REST API, whether using object type `sql/warehouses` or `warehouses`, the API returns permissions for the same resources: ``` 15:13:01 DEBUG GET /api/2.0/permissions/sql/warehouses/<ID> < HTTP/2.0 200 OK < { < "access_control_list": [ < { < "all_permissions": [ < { < "inherited": false, < "permission_level": "IS_OWNER" < } < ], < "display_name": "<ME>", < "user_name": "<ME>" < }, < { < "all_permissions": [ < { < "inherited": true, < "inherited_from_object": [ < "/sql/warehouses/" < ], < "permission_level": "CAN_MANAGE" < } < ], < "group_name": "admins" < } < ], < "object_id": "/sql/warehouses/<ID>", < "object_type": "warehouses" < } pid=53287 sdk=true ... 15:12:56 DEBUG GET /api/2.0/permissions/warehouses/<ID> < HTTP/2.0 200 OK < { < "access_control_list": [ < { < "all_permissions": [ < { < "inherited": false, < "permission_level": "IS_OWNER" < } < ], < "display_name": "<ME>", < "user_name": "<ME>" < }, < { < "all_permissions": [ < { < "inherited": true, < "inherited_from_object": [ < "/sql/warehouses/" < ], < "permission_level": "CAN_MANAGE" < } < ], < "group_name": "admins" < } < ], < "object_id": "/sql/warehouses/<ID>", < "object_type": "warehouses" < } pid=53248 sdk=true ``` This PR modifies the SQL warehouse configuration for `databricks_permissions` to be chosen for instances with an ID of the form `/warehouses/...`. ## Tests The additional integration test ensures that a resource can be imported with the `/warehouses/<ID>` format.
Changes
In c441517, a check was added to prevent users from assigning any permissions for themselves in
databricks_permissions. This unfortunately makes it impossible for users to legitimately assign themselves as the owner of certain resources, such as jobs, if they are currently owned by a different principal. This PR removes this unnecessary restriction. If the user requests to set permissions for an object in a way that is incompatible with the object, such as removing themselves as owner, the failure will be propagated from the backend to the user instead. This does not make any changes to the way the ownership ACLs are set up (e.g. for resources that require an owner, like jobs, if the Terraform user did not specify an owner, the provider will still set the current user as the owner).This PR also refactors the permissions resource substantially. The logic for implementing each resource type's permissions, including the field name, object type and resource-specific modifications, are all colocated with the resource's own definition. The type encapsulating this is called
resourcePermissions. As a result, the control flow is easier to follow:Customizations are defined in the permissions/read and permissions/update packages. For update, a mini expression language is defined to support conditional application of customizations.
Lastly, this PR also migrates the resource to the Databricks SDK.
Fixes #2407.
Tests
This PR adds integration test coverage for the
databricks_permissionsresource for nearly all supported resource types. I wasn't able to run the integration test forauthorization = "passwords"because password-based auth is deprecated, nor for serving endpoints because of a likely race condition.Integration tests cover all permission levels, and all principal types. Included is special edge case testing for root directory and all registered models.
make testrun locallydocs/folderinternal/acceptance