Skip to content

Commit 51df18a

Browse files
authored
Support clusters in bundle-level permissions (#3916)
## Why Seems like a gap - users expect at least CAN_MANAGE at target level to apply to clusters as well. ## Tests New acceptance test.
1 parent f6a35c5 commit 51df18a

File tree

10 files changed

+190
-9
lines changed

10 files changed

+190
-9
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
targets:
2+
dev:
3+
mode: development
4+
default: true
5+
permissions:
6+
- level: CAN_VIEW
7+
service_principal_name: 6a6ffa73-af58-4f47-94cd-bed9ffcc1234
8+
- level: CAN_RUN
9+
service_principal_name: 6a6ffa73-af58-4f47-94cd-bed9ffcc3456
10+
- level: CAN_MANAGE
11+
service_principal_name: 6a6ffa73-af58-4f47-94cd-bed9ffcc4567
12+
- level: CAN_RUN
13+
user_name: [email protected]
14+
15+
resources:
16+
clusters:
17+
cluster1:
18+
cluster_name: test-cluster
19+
spark_version: 15.4.x-scala2.12
20+
node_type_id: i3.xlarge
21+
num_workers: 1
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"method": "POST",
3+
"path": "/api/2.1/clusters/create",
4+
"body": {
5+
"autotermination_minutes": 60,
6+
"cluster_name": "[dev [USERNAME]] test-cluster",
7+
"custom_tags": {
8+
"dev": "[USERNAME]"
9+
},
10+
"node_type_id": "[NODE_TYPE_ID]",
11+
"num_workers": 1,
12+
"spark_version": "15.4.x-scala2.12"
13+
}
14+
}
15+
{
16+
"method": "PUT",
17+
"path": "/api/2.0/permissions/clusters/[UUID]",
18+
"body": {
19+
"access_control_list": [
20+
{
21+
"permission_level": "CAN_ATTACH_TO",
22+
"service_principal_name": "[UUID]"
23+
},
24+
{
25+
"permission_level": "CAN_RESTART",
26+
"service_principal_name": "[UUID]"
27+
},
28+
{
29+
"permission_level": "CAN_MANAGE",
30+
"service_principal_name": "[UUID]"
31+
},
32+
{
33+
"permission_level": "CAN_MANAGE",
34+
"user_name": "[USERNAME]"
35+
}
36+
]
37+
}
38+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"method": "POST",
3+
"path": "/api/2.1/clusters/create",
4+
"body": {
5+
"autotermination_minutes": 60,
6+
"cluster_name": "[dev [USERNAME]] test-cluster",
7+
"custom_tags": {
8+
"dev": "[USERNAME]"
9+
},
10+
"node_type_id": "[NODE_TYPE_ID]",
11+
"num_workers": 1,
12+
"spark_version": "15.4.x-scala2.12"
13+
}
14+
}
15+
{
16+
"method": "PUT",
17+
"path": "/api/2.0/permissions/clusters/[UUID]",
18+
"body": {
19+
"access_control_list": [
20+
{
21+
"permission_level": "CAN_MANAGE",
22+
"service_principal_name": "[UUID]"
23+
},
24+
{
25+
"permission_level": "CAN_ATTACH_TO",
26+
"service_principal_name": "[UUID]"
27+
},
28+
{
29+
"permission_level": "CAN_RESTART",
30+
"service_principal_name": "[UUID]"
31+
},
32+
{
33+
"permission_level": "CAN_MANAGE",
34+
"user_name": "[USERNAME]"
35+
}
36+
]
37+
}
38+
}

acceptance/bundle/resources/permissions/clusters/target/out.test.toml

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
2+
>>> [CLI] bundle validate -o json
3+
Recommendation: permissions section should explicitly include the current deployment identity '[USERNAME]' or one of its groups
4+
If it is not included, CAN_MANAGE permissions are only applied if the present identity is used to deploy.
5+
6+
Consider using a adding a top-level permissions section such as the following:
7+
8+
permissions:
9+
- user_name: [USERNAME]
10+
level: CAN_MANAGE
11+
12+
See https://docs.databricks.com/dev-tools/bundles/permissions.html to learn more about permission configuration.
13+
in databricks.yml:15:7
14+
15+
{
16+
"clusters": {
17+
"cluster1": {
18+
"autotermination_minutes": 60,
19+
"cluster_name": "[dev [USERNAME]] test-cluster",
20+
"custom_tags": {
21+
"dev": "[USERNAME]"
22+
},
23+
"node_type_id": "[NODE_TYPE_ID]",
24+
"num_workers": 1,
25+
"permissions": [
26+
{
27+
"level": "CAN_ATTACH_TO",
28+
"service_principal_name": "[UUID]"
29+
},
30+
{
31+
"level": "CAN_RESTART",
32+
"service_principal_name": "[UUID]"
33+
},
34+
{
35+
"level": "CAN_MANAGE",
36+
"service_principal_name": "[UUID]"
37+
},
38+
{
39+
"level": "CAN_MANAGE",
40+
"user_name": "[USERNAME]"
41+
}
42+
],
43+
"spark_version": "15.4.x-scala2.12"
44+
}
45+
}
46+
}
47+
48+
>>> [CLI] bundle deploy
49+
Recommendation: permissions section should explicitly include the current deployment identity '[USERNAME]' or one of its groups
50+
If it is not included, CAN_MANAGE permissions are only applied if the present identity is used to deploy.
51+
52+
Consider using a adding a top-level permissions section such as the following:
53+
54+
permissions:
55+
- user_name: [USERNAME]
56+
level: CAN_MANAGE
57+
58+
See https://docs.databricks.com/dev-tools/bundles/permissions.html to learn more about permission configuration.
59+
in databricks.yml:15:7
60+
61+
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/dev/files...
62+
Deploying resources...
63+
Updating deployment state...
64+
Deployment complete!
65+
66+
>>> print_requests.py //clusters
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
trace $CLI bundle validate -o json | jq .resources
2+
trace $CLI bundle deploy
3+
trace print_requests.py //clusters > out.requests.$DATABRICKS_BUNDLE_ENGINE.json

acceptance/bundle/resources/permissions/output.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ DIFF clusters/current_can_manage/out.requests.destroy.direct.json
5555
+ "path": "/api/2.0/permissions/clusters/[UUID]"
5656
+ }
5757
+]
58+
MATCH clusters/target/out.requests.direct.json
5859
MATCH database_instances/current_can_manage/out.requests.deploy.direct.json
5960
DIFF database_instances/current_can_manage/out.requests.destroy.direct.json
6061
--- database_instances/current_can_manage/out.requests.destroy.direct.json

acceptance/bundle/validate/empty_resources/with_permissions/output.txt

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,7 @@ Warning: required field "schema_name" is not set
134134
{
135135
"clusters": {
136136
"rname": {
137-
"autotermination_minutes": 60,
138-
"permissions": [
139-
{
140-
"level": "CAN_MANAGE",
141-
"user_name": "[USERNAME]"
142-
}
143-
]
137+
"autotermination_minutes": 60
144138
}
145139
}
146140
}

bundle/config/mutator/resourcemutator/apply_bundle_permissions.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ import (
1515
"github.com/databricks/cli/libs/dyn/convert"
1616
)
1717

18-
var unsupportedResources = []string{"clusters", "volumes", "schemas", "quality_monitors", "registered_models", "database_catalogs", "synced_database_tables"}
19-
2018
var (
2119
allowedLevels = []string{permissions.CAN_MANAGE, permissions.CAN_VIEW, permissions.CAN_RUN}
2220
levelsMap = map[string](map[string]string){
@@ -69,6 +67,12 @@ var (
6967
permissions.CAN_MANAGE: "CAN_MANAGE",
7068
permissions.CAN_VIEW: "CAN_USE",
7169
},
70+
"clusters": {
71+
// https://docs.databricks.com/aws/en/security/auth/access-control/#compute-acls
72+
permissions.CAN_MANAGE: "CAN_MANAGE",
73+
permissions.CAN_VIEW: "CAN_ATTACH_TO",
74+
permissions.CAN_RUN: "CAN_RESTART",
75+
},
7276
}
7377
)
7478

bundle/config/mutator/resourcemutator/apply_bundle_permissions_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@ import (
1616
"github.com/stretchr/testify/require"
1717
)
1818

19+
// This list exists to ensure that this mutator is updated when new resource is added.
20+
// These resources are there because they use grants, not permissions:
21+
var unsupportedResources = []string{
22+
"volumes",
23+
"schemas",
24+
"quality_monitors",
25+
"registered_models",
26+
"database_catalogs",
27+
"synced_database_tables",
28+
}
29+
1930
func TestApplyBundlePermissions(t *testing.T) {
2031
b := &bundle.Bundle{
2132
Config: config.Root{

0 commit comments

Comments
 (0)