Skip to content

Commit 08123e4

Browse files
pieternclaude
andauthored
Simulate app service principal and job permissions in test server (#4644)
## Summary - Make the test server assign a service principal to apps and grant permissions on referenced resources, mimicking real platform behavior - Add an acceptance test that exercises the permission lifecycle across multiple deploys - Refactor `SetPermissions` dedup logic into a shared `upsertACL` helper The acceptance test is restricted to the terraform engine. The direct engine fails during planning: ``` cannot set (*dresources.PermissionsState).[0].service_principal_name to string: failed to navigate to parent [0]: cannot index struct ``` ## Test plan - [x] All acceptance tests pass - [x] Verified direct engine failure mode separately Relates to #4309 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5f353a0 commit 08123e4

14 files changed

Lines changed: 208 additions & 36 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
print("hello")
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
bundle:
2+
name: test-bundle
3+
4+
permissions:
5+
- level: CAN_MANAGE
6+
user_name: ${workspace.current_user.userName}
7+
8+
resources:
9+
jobs:
10+
my_job:
11+
name: my-job
12+
tasks:
13+
- task_key: hello
14+
environment_key: default
15+
spark_python_task:
16+
python_file: ./hello.py
17+
environments:
18+
- environment_key: default
19+
spec:
20+
client: "1"
21+
22+
apps:
23+
my_app:
24+
name: my-app
25+
source_code_path: ./app
26+
resources:
27+
- name: my-job
28+
job:
29+
id: ${resources.jobs.my_job.id}
30+
permission: CAN_MANAGE_RUN
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--- a/databricks.yml
2+
+++ b/databricks.yml
3+
@@ -10,6 +10,9 @@
4+
my_job:
5+
name: my-job
6+
+ permissions:
7+
+ - level: CAN_MANAGE_RUN
8+
+ service_principal_name: ${resources.apps.my_app.service_principal_client_id}
9+
tasks:
10+
- task_key: hello
11+
environment_key: default
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
print("hello")

acceptance/bundle/apps/job_permissions/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: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
>>> [CLI] bundle deploy
3+
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
4+
Deploying resources...
5+
Updating deployment state...
6+
Deployment complete!
7+
8+
=== After first deploy
9+
>>> has_manage_run
10+
true
11+
12+
=== After second deploy
13+
>>> [CLI] bundle deploy
14+
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
15+
Deploying resources...
16+
Updating deployment state...
17+
Deployment complete!
18+
19+
>>> has_manage_run
20+
false
21+
22+
=== Apply fix and redeploy
23+
>>> [CLI] bundle deploy
24+
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
25+
Deploying resources...
26+
Updating deployment state...
27+
Deployment complete!
28+
29+
>>> has_manage_run
30+
true
31+
32+
>>> [CLI] bundle destroy --auto-approve
33+
The following resources will be deleted:
34+
delete resources.apps.my_app
35+
delete resources.jobs.my_job
36+
37+
All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default
38+
39+
Deleting files...
40+
Destroy complete!
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
# Test that app-granted permissions on a job survive a second deploy.
3+
# Issue: https://github.com/databricks/cli/issues/4309
4+
5+
trace $CLI bundle deploy
6+
7+
job_id=$(read_id.py my_job)
8+
9+
has_manage_run() {
10+
MSYS_NO_PATHCONV=1 $CLI api get /api/2.0/permissions/jobs/$job_id \
11+
| jq 'any(.access_control_list[].all_permissions[]; .permission_level == "CAN_MANAGE_RUN")'
12+
}
13+
14+
title "After first deploy"
15+
trace has_manage_run
16+
17+
title "After second deploy"
18+
trace $CLI bundle deploy
19+
trace has_manage_run
20+
21+
title "Apply fix and redeploy"
22+
patch -s --no-backup-if-mismatch databricks.yml < fix.patch
23+
trace $CLI bundle deploy
24+
trace has_manage_run
25+
26+
trace $CLI bundle destroy --auto-approve
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Direct engine error: cannot plan resources.jobs.my_job.permissions: cannot update
2+
# [0].service_principal_name: failed to navigate to parent [0]: [0]: cannot index struct.
3+
# This is a bug in structaccess.Set() where it fails to index into a struct when
4+
# setting permissions with service_principal_name.
5+
# See https://github.com/databricks/cli/pull/4644
6+
Badness = "Direct engine fails to plan permissions with service_principal_name on jobs"
7+
Cloud = true
8+
RecordRequests = false
9+
10+
[EnvMatrix]
11+
DATABRICKS_BUNDLE_ENGINE = ["terraform"]

acceptance/bundle/generate/app_not_yet_deployed/output.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
},
1212
"id":"1000",
1313
"name":"my-app",
14+
"service_principal_client_id":"[UUID]",
15+
"service_principal_id":[NUMID],
16+
"service_principal_name":"app-my-app",
1417
"url":"my-app-123.cloud.databricksapps.com"
1518
}
1619

acceptance/bundle/resources/apps/create_already_exists/output.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
},
1212
"id":"1000",
1313
"name":"test-app-already-exists",
14+
"service_principal_client_id":"[UUID]",
15+
"service_principal_id":[NUMID],
16+
"service_principal_name":"app-test-app-already-exists",
1417
"url":"test-app-already-exists-123.cloud.databricksapps.com"
1518
}
1619

0 commit comments

Comments
 (0)