Skip to content

Encode tag key as a single path segment in tag-policy and tag-assignment APIs#1713

Closed
lizhenxiang-db wants to merge 1 commit into
databricks:mainfrom
lizhenxiang-db:tag-policy-encode-path-key
Closed

Encode tag key as a single path segment in tag-policy and tag-assignment APIs#1713
lizhenxiang-db wants to merge 1 commit into
databricks:mainfrom
lizhenxiang-db:tag-policy-encode-path-key

Conversation

@lizhenxiang-db

@lizhenxiang-db lizhenxiang-db commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Percent-encode the governed tag key when it travels as a URL path parameter across the tag-policy and entity-tag-assignment APIs, so keys containing / route to the correct endpoint.

Why

Governed tag keys may be hierarchical and contain / (e.g. a/b). The generated clients interpolate the key straight into the request path (e.g. fmt.Sprintf("/api/2.1/tag-policies/%v", request.TagKey)), so a raw / is treated as a path separator and the request resolves to no matching endpoint (404 / ENDPOINT_NOT_FOUND). Get, Delete, and Update are affected.

A concrete consequence: the Terraform provider cannot refresh a databricks_tag_policy whose key contains / — every plan reads it as missing and tries to recreate it, which then fails because the policy already exists.

Create does not have this problem: it sends the key in the JSON request body, where / is valid and must be stored verbatim.

What changed

Interface changes

None. Method signatures are unchanged; only the encoding of the existing request path differs.

Behavioral changes

The tag-key path parameter is now url.PathEscaped (/%2F) before the request is sent, in:

  • tags.TagPoliciesAPIGetTagPolicy, DeleteTagPolicy, UpdateTagPolicy
  • tags.WorkspaceEntityTagAssignmentsAPIGetTagAssignment, DeleteTagAssignment, UpdateTagAssignment
  • catalog.EntityTagAssignmentsAPIGet, Delete, Update

The server decodes the key back to its original value, so behavior is unchanged for keys without special characters and fixed for keys that contain them. Only the tag-key parameter is encoded — entity_type / entity_id / entity_name are left untouched. The Create methods are intentionally not overridden (they send the key in the body).

Internal changes

  • service/tags/ext_impl.go — hand-written overrides for TagPoliciesAPI and WorkspaceEntityTagAssignmentsAPI.
  • service/catalog/ext_entity_tag_assignments.go — hand-written overrides for EntityTagAssignmentsAPI.
  • NEXT_CHANGELOG.md — Bug Fixes entry.

How is this tested?

qa.HTTPFixtures unit tests in service/tags/ext_impl_test.go and service/catalog/ext_entity_tag_assignments_test.go assert the request path is encoded (/%2F) for the tag-policy and both entity-tag-assignment APIs. go build, go vet, and go test pass locally for both packages.

This pull request and its description were written by Isaac.

…ent APIs

Governed tag keys may be hierarchical and contain "/" (e.g. "a/b"). The generated
clients interpolate the key straight into the request path, so a raw "/" is
treated as a path separator and the request resolves to no matching endpoint
(404 / ENDPOINT_NOT_FOUND). Get, Delete, and Update are affected.

Add hand-written overrides that url.PathEscape the tag-key path parameter before
delegating to the generated impl; the server decodes it back to the original key.
Covers:
- tags.TagPoliciesAPI: Get/Delete/UpdateTagPolicy
- tags.WorkspaceEntityTagAssignmentsAPI: Get/Delete/UpdateTagAssignment
- catalog.EntityTagAssignmentsAPI: Get/Delete/Update

Only the tag-key path parameter is encoded; entity_type/entity_id/entity_name are
left untouched. The Create methods are intentionally not overridden -- they send
the key in the JSON body, where "/" is valid and must be stored verbatim.

Co-authored-by: Isaac
Signed-off-by: Lizhen Xiang <lizhen.xiang@databricks.com>
@lizhenxiang-db lizhenxiang-db force-pushed the tag-policy-encode-path-key branch from dba604c to a336c9b Compare June 10, 2026 18:56
@github-actions

Copy link
Copy Markdown

If integration tests don't run automatically, an authorized user can run them manually by following the instructions below:

Trigger:
go/deco-tests-run/sdk-go

Inputs:

  • PR number: 1713
  • Commit SHA: a336c9ba763c8b52302863493becbbbb40392a8c

Checks will be approved automatically on success.

@lizhenxiang-db lizhenxiang-db changed the title Encode tag policy key as a single path segment in Get/Delete/UpdateTagPolicy Encode tag key as a single path segment in tag-policy and tag-assignment APIs Jun 10, 2026
@renaudhartert-db

Copy link
Copy Markdown
Contributor

For context, the failing checks here are not caused by the change: this PR is opened from a personal fork, and fork PRs do not receive GitHub Actions OIDC tokens, so setup-build-environment fails at JFrog auth before tests run. Required checks can therefore never pass on this PR. I pushed the same commits to an origin branch as #1716 so CI can run; I will close this one once #1716 merges.

@renaudhartert-db

Copy link
Copy Markdown
Contributor

Merged via #1716 (identical commits, squashed into main as part of the merge queue). Closing this one since fork PRs cannot pass the OIDC-gated required checks. Thanks for the fix @lizhenxiang-db.

alexott pushed a commit to alexott/databricks-sdk-go that referenced this pull request Jun 17, 2026
…ent APIs (databricks#1716)

> [!NOTE]
> Supersedes databricks#1713 with identical commits, authored by @lizhenxiang-db.
That PR was opened from a personal fork, and fork PRs do not receive
GitHub Actions OIDC tokens, so the required `tests` checks fail at JFrog
authentication before running anything and the PR can never enter the
merge queue. This PR carries the same branch pushed to `origin` so CI
can run.

## Summary

Percent-encode the governed tag key when it travels as a URL *path*
parameter across the tag-policy and entity-tag-assignment APIs, so keys
containing `/` route to the correct endpoint.

## Why

Governed tag keys may be hierarchical and contain `/` (e.g. `a/b`). The
generated clients interpolate the key straight into the request path
(e.g. `fmt.Sprintf("/api/2.1/tag-policies/%v", request.TagKey)`), so a
raw `/` is treated as a path separator and the request resolves to no
matching endpoint (`404` / `ENDPOINT_NOT_FOUND`). `Get`, `Delete`, and
`Update` are affected.

A concrete consequence: the Terraform provider cannot refresh a
`databricks_tag_policy` whose key contains `/`: every plan reads it as
missing and tries to recreate it, which then fails because the policy
already exists.

`Create` does not have this problem: it sends the key in the JSON
request body, where `/` is valid and must be stored verbatim.

## What changed

### Interface changes

None. Method signatures are unchanged; only the encoding of the existing
request path differs.

### Behavioral changes

The tag-key path parameter is now `url.PathEscape`d (`/` becomes `%2F`)
before the request is sent, in:

- **`tags.TagPoliciesAPI`**: `GetTagPolicy`, `DeleteTagPolicy`,
`UpdateTagPolicy`
- **`tags.WorkspaceEntityTagAssignmentsAPI`**: `GetTagAssignment`,
`DeleteTagAssignment`, `UpdateTagAssignment`
- **`catalog.EntityTagAssignmentsAPI`**: `Get`, `Delete`, `Update`

The server decodes the key back to its original value, so behavior is
unchanged for keys without special characters and fixed for keys that
contain them. Only the tag-key parameter is encoded; `entity_type` /
`entity_id` / `entity_name` are left untouched. The `Create` methods are
intentionally not overridden (they send the key in the body).

### Internal changes

- `service/tags/ext_impl.go`: hand-written overrides for
`TagPoliciesAPI` and `WorkspaceEntityTagAssignmentsAPI`.
- `service/catalog/ext_entity_tag_assignments.go`: hand-written
overrides for `EntityTagAssignmentsAPI`.
- `NEXT_CHANGELOG.md`: Bug Fixes entry.

## How is this tested?

`qa.HTTPFixtures` unit tests in `service/tags/ext_impl_test.go` and
`service/catalog/ext_entity_tag_assignments_test.go` assert the request
path is encoded (`/` becomes `%2F`) for the tag-policy and both
entity-tag-assignment APIs. The full `make test` suite (1439 tests) and
`make lint` pass locally on this branch merged with latest `main`.

Signed-off-by: Lizhen Xiang <lizhen.xiang@databricks.com>
Co-authored-by: Lizhen Xiang <lizhen.xiang@databricks.com>
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