Skip to content

direct: Fix permissions state path to match input config schema#4703

Open
denik wants to merge 50 commits intomainfrom
denik/permissions-reference
Open

direct: Fix permissions state path to match input config schema#4703
denik wants to merge 50 commits intomainfrom
denik/permissions-reference

Conversation

@denik
Copy link
Contributor

@denik denik commented Mar 11, 2026

Changes

  • Add EmbeddedSlice field name convention to struct walkers in libs/structs/ — when a struct field is named EmbeddedSlice, walkers treat it as transparent (no path segment added), so its elements appear directly at the parent path
  • Apply this to PermissionsState: rename Permissions field to EmbeddedSlice, making state paths like resources.jobs.foo.permissions[0] match input config paths (previously resources.jobs.foo.permissions.permissions[0])
  • Fix refschema output: permissions.[*]permissions[*] (remove spurious dot before bracket)
  • Enable job_permissions acceptance test for direct engine

Why

The direct deployment engine's permissions state used a wrapper struct that added an extra permissions segment to paths. This caused a mismatch with input config paths, preventing dependency tracking between permissions and their parent resources. With this fix, state and config paths are consistent.

@eng-dev-ecosystem-bot
Copy link
Collaborator

eng-dev-ecosystem-bot commented Mar 11, 2026

Commit: 7824eb6

Run: 22977576168

Env 🪲​BUG ❌​FAIL 🟨​KNOWN 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
🪲​ aws linux 1 1 1 7 7 266 783 10:09
🪲​ aws windows 1 1 1 7 7 268 781 6:42
🪲​ aws-ucws linux 1 5 1 7 7 359 698 8:44
🪲​ aws-ucws windows 1 5 1 1 7 7 360 696 8:02
🪲​ azure linux 1 1 1 1 9 269 781 8:33
🪲​ azure windows 1 1 1 1 9 271 779 5:48
🪲​ azure-ucws linux 1 5 1 2 9 363 694 12:45
🪲​ azure-ucws windows 1 5 1 1 1 9 365 692 9:04
💚​ gcp linux 2 9 267 784 9:41
💚​ gcp windows 2 9 269 782 5:23
22 interesting tests: 7 SKIP, 6 RECOVERED, 5 FAIL, 2 flaky, 1 KNOWN, 1 BUG
Test Name aws linux aws windows aws-ucws linux aws-ucws windows azure linux azure windows azure-ucws linux azure-ucws windows gcp linux gcp windows
🟨​ TestAccept 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 💚​R 💚​R
❌​ TestAccept/bundle/resources/model_serving_endpoints/basic 🙈​s 🙈​s ❌​F ❌​F 🙈​s 🙈​s ❌​F ❌​F 🙈​s 🙈​s
❌​ TestAccept/bundle/resources/model_serving_endpoints/basic/DATABRICKS_BUNDLE_ENGINE=direct ❌​F ❌​F ❌​F ❌​F
🙈​ TestAccept/bundle/resources/permissions 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🪲​ TestAccept/bundle/resources/permissions/dashboards/create 🪲​B 🪲​B 🪲​B 🪲​B 🪲​B 🪲​B 🪲​B 🪲​B 🙈​s 🙈​s
❌​ TestAccept/bundle/resources/permissions/dashboards/create/DATABRICKS_BUNDLE_ENGINE=direct ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F ❌​F
❌​ TestAccept/bundle/resources/permissions/jobs/delete_one/cloud 🙈​s 🙈​s ❌​F ❌​F 🙈​s 🙈​s ❌​F ❌​F 🙈​s 🙈​s
❌​ TestAccept/bundle/resources/permissions/jobs/delete_one/cloud/DATABRICKS_BUNDLE_ENGINE=direct ❌​F ❌​F ❌​F ❌​F
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions 💚​R 💚​R 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=direct 💚​R 💚​R 💚​R 💚​R
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 💚​R 💚​R 💚​R 💚​R
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions 💚​R 💚​R 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=direct 💚​R 💚​R 💚​R 💚​R
💚​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 💚​R 💚​R 💚​R 💚​R
🙈​ TestAccept/bundle/resources/postgres_branches/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/recreate 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/update_protected 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_branches/without_branch_id 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/postgres_endpoints/recreate 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🙈​ TestAccept/bundle/resources/synced_database_tables/basic 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🔄​ TestAccept/ssh/connect-serverless-gpu 🙈​s 🙈​s ✅​p 🔄​f 🙈​s 🙈​s 🔄​f 🔄​f 🙈​s 🙈​s
🔄​ TestAccept/ssh/connection 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 🔄​f 💚​R 💚​R 💚​R
Top 33 slowest tests (at least 2 minutes):
duration env testname
6:44 gcp linux TestAccept/ssh/connection
6:28 aws linux TestAccept/ssh/connection
6:02 gcp linux TestSecretsPutSecretStringValue
5:19 aws-ucws linux TestAccept/ssh/connection
5:10 azure-ucws linux TestSecretsPutSecretStringValue
5:09 aws linux TestSecretsPutSecretStringValue
5:00 azure linux TestAccept/ssh/connection
4:53 azure-ucws windows TestSecretsPutSecretStringValue
3:57 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:57 gcp windows TestSecretsPutSecretStringValue
3:52 azure linux TestSecretsPutSecretStringValue
3:45 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:44 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:40 gcp windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:37 gcp linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:25 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:18 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:15 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:14 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
3:12 aws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:11 gcp windows TestAccept/ssh/connection
3:05 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
3:03 aws-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:50 aws windows TestAccept/ssh/connection
2:41 aws-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:38 azure windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:36 aws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:22 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:19 azure-ucws windows TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:17 aws-ucws linux TestAccept/ssh/connect-serverless-gpu
2:11 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform
2:11 azure linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
2:05 azure-ucws linux TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct

@denik denik temporarily deployed to test-trigger-is March 11, 2026 10:41 — with GitHub Actions Inactive
@denik denik force-pushed the denik/permissions-reference branch from 66d736a to cf0178e Compare March 11, 2026 16:07
@denik denik temporarily deployed to test-trigger-is March 11, 2026 16:08 — with GitHub Actions Inactive
@denik denik temporarily deployed to test-trigger-is March 11, 2026 16:46 — with GitHub Actions Inactive
@denik denik temporarily deployed to test-trigger-is March 11, 2026 16:49 — with GitHub Actions Inactive
denik and others added 17 commits March 11, 2026 21:58
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces the __EMBED__ JSON tag convention. When a struct field
has json:"__EMBED__", struct walkers treat it as transparent and
don't add its name to the path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fields with json:"__EMBED__" are walked at the parent path level,
making their contents appear directly without the field name in paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fields with json:"__EMBED__" are walked at the parent path level
in type traversal, consistent with Walk behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When navigating a struct and the path expects an index or key-value
selector, transparently navigate through the __EMBED__ field.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When setting a value at an index node and the parent is a struct,
transparently navigate through the __EMBED__ field.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When validating paths with index, bracket-star, or key-value nodes
on a struct type, transparently navigate through __EMBED__ fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fields with json:"__EMBED__" are diffed at the parent path level,
consistent with how anonymous embedding works.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This makes the permissions slice appear at the root path of
PermissionsState, matching the input config schema where permissions
are accessed as resources.jobs.foo.permissions[0].

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The __EMBED__ convention on PermissionsState fixes the structaccess.Set()
bug that prevented the direct engine from planning permissions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The __EMBED__ tag is for struct walkers only; JSON serialization must still
use "permissions" as the field name. Add MarshalJSON/UnmarshalJSON to
PermissionsState using a shadow struct. Regenerate all acceptance test
outputs to reflect the corrected permission paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Struct walkers now check for EmbeddedSliceFieldName constant
instead of parsing the __EMBED__ json tag via IsEmbed(). The
IsEmbed() method is removed from JSONTag.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
denik and others added 28 commits March 11, 2026 21:58
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This reverts commit 410bd9b.
The splitResourcePath helper correctly routes references like
${resources.jobs.foo.permissions[0].level} to the permissions
sub-resource node instead of trying to find "permissions" field
on jobs.JobSettings.

Co-authored-by: Isaac
Add test that demonstrates cross-resource permission references:
job_a's permission levels reference job_b's permission levels via
${resources.jobs.job_b.permissions[0].level} syntax.

Fix splitResourcePath to correctly route permission sub-resource
references. Add level→permission_level field remapping since input
config uses "level" but state uses "permission_level".

Co-authored-by: Isaac
The plan JSON already verifies resolved permission levels. Deploy
confirms the resolution succeeds end-to-end. Request recording
disabled to avoid non-deterministic output ordering.

Co-authored-by: Isaac
…trolRequest

This eliminates the level→permission_level field remapping since
resources.Permission uses json:"level" matching the input config.
…deserialization

StatePermission type has both "level" and "permission_level" JSON fields.
UnmarshalJSON migrates old state files that used "permission_level"
(from iam.AccessControlRequest) to the current "level" field.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@denik denik force-pushed the denik/permissions-reference branch from 849df2a to 7824eb6 Compare March 11, 2026 22:31
@denik denik temporarily deployed to test-trigger-is March 11, 2026 22:31 — with GitHub Actions Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants