Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEXT_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### CLI

### Bundles
* Modify grants to use SDK types ([#4666](https://github.com/databricks/cli/pull/4666))

### Dependency updates

Expand Down
9 changes: 9 additions & 0 deletions acceptance/bundle/python/grants-aliases/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
bundle:
name: my_project

sync: {paths: []} # don't need to copy files

experimental:
python:
resources:
- "resources:load_resources"
6 changes: 6 additions & 0 deletions acceptance/bundle/python/grants-aliases/out.test.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 39 additions & 0 deletions acceptance/bundle/python/grants-aliases/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

>>> uv run --with-requirements requirements-latest.txt --no-cache -q [CLI] bundle validate --output json
{
"experimental": {
"python": {
"resources": [
"resources:load_resources"
]
}
},
"resources": {
"schemas": {
"my_schema": {
"catalog_name": "my_catalog",
"grants": [
{
"principal": "data-team@example.com",
"privileges": [
"USE_SCHEMA"
]
}
],
"name": "my_schema"
},
"my_schema_legacy": {
"catalog_name": "my_catalog",
"grants": [
{
"principal": "data-team@example.com",
"privileges": [
"USE_SCHEMA"
]
}
],
"name": "my_schema_legacy"
}
}
}
}
43 changes: 43 additions & 0 deletions acceptance/bundle/python/grants-aliases/resources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from databricks.bundles.core import Resources

# New unified types (preferred going forward)
from databricks.bundles.schemas import Privilege, PrivilegeAssignment

# Old per-resource aliases (kept for backward compatibility)
from databricks.bundles.schemas import SchemaGrant, SchemaGrantPrivilege


def load_resources() -> Resources:
resources = Resources()

resources.add_schema(
"my_schema",
{
"name": "my_schema",
"catalog_name": "my_catalog",
# New type
"grants": [
PrivilegeAssignment(
principal="data-team@example.com",
privileges=[Privilege.USE_SCHEMA],
)
],
},
)

resources.add_schema(
"my_schema_legacy",
{
"name": "my_schema_legacy",
"catalog_name": "my_catalog",
# Old alias type — identical to PrivilegeAssignment at runtime
"grants": [
SchemaGrant(
principal="data-team@example.com",
privileges=[SchemaGrantPrivilege.USE_SCHEMA],
)
],
},
)

return resources
6 changes: 6 additions & 0 deletions acceptance/bundle/python/grants-aliases/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
echo "$DATABRICKS_BUNDLES_WHEEL" > "requirements-latest.txt"

trace uv run $UV_ARGS -q $CLI bundle validate --output json | \
jq "pick(.experimental.python, .resources)"

rm -fr .databricks __pycache__
7 changes: 7 additions & 0 deletions acceptance/bundle/python/grants-aliases/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Local = true
Cloud = false # tests don't interact with APIs

[EnvMatrix]
UV_ARGS = [
"--with-requirements requirements-latest.txt --no-cache",
]
60 changes: 30 additions & 30 deletions acceptance/bundle/refschema/out.fields.txt
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,11 @@ resources.catalogs.*.effective_predictive_optimization_flag.inherited_from_type
resources.catalogs.*.effective_predictive_optimization_flag.value catalog.EnablePredictiveOptimization REMOTE
resources.catalogs.*.enable_predictive_optimization catalog.EnablePredictiveOptimization REMOTE
resources.catalogs.*.full_name string REMOTE
resources.catalogs.*.grants []resources.CatalogGrant INPUT
resources.catalogs.*.grants[*] resources.CatalogGrant INPUT
resources.catalogs.*.grants []catalog.PrivilegeAssignment INPUT
resources.catalogs.*.grants[*] catalog.PrivilegeAssignment INPUT
resources.catalogs.*.grants[*].principal string INPUT
resources.catalogs.*.grants[*].privileges []resources.CatalogGrantPrivilege INPUT
resources.catalogs.*.grants[*].privileges[*] resources.CatalogGrantPrivilege INPUT
resources.catalogs.*.grants[*].privileges []catalog.Privilege INPUT
resources.catalogs.*.grants[*].privileges[*] catalog.Privilege INPUT
resources.catalogs.*.id string INPUT
resources.catalogs.*.isolation_mode catalog.CatalogIsolationMode REMOTE
resources.catalogs.*.lifecycle resources.Lifecycle INPUT
Expand All @@ -261,8 +261,8 @@ resources.catalogs.*.updated_at int64 REMOTE
resources.catalogs.*.updated_by string REMOTE
resources.catalogs.*.url string INPUT
resources.catalogs.*.grants.full_name string ALL
resources.catalogs.*.grants.grants []dresources.GrantAssignment ALL
resources.catalogs.*.grants.grants[*] dresources.GrantAssignment ALL
resources.catalogs.*.grants.grants []catalog.PrivilegeAssignment ALL
resources.catalogs.*.grants.grants[*] catalog.PrivilegeAssignment ALL
resources.catalogs.*.grants.grants[*].principal string ALL
resources.catalogs.*.grants.grants[*].privileges []catalog.Privilege ALL
resources.catalogs.*.grants.grants[*].privileges[*] catalog.Privilege ALL
Expand Down Expand Up @@ -710,11 +710,11 @@ resources.external_locations.*.file_event_queue.provided_pubsub.subscription_nam
resources.external_locations.*.file_event_queue.provided_sqs *catalog.AwsSqsQueue ALL
resources.external_locations.*.file_event_queue.provided_sqs.managed_resource_id string ALL
resources.external_locations.*.file_event_queue.provided_sqs.queue_url string ALL
resources.external_locations.*.grants []resources.ExternalLocationGrant INPUT
resources.external_locations.*.grants[*] resources.ExternalLocationGrant INPUT
resources.external_locations.*.grants []catalog.PrivilegeAssignment INPUT
resources.external_locations.*.grants[*] catalog.PrivilegeAssignment INPUT
resources.external_locations.*.grants[*].principal string INPUT
resources.external_locations.*.grants[*].privileges []resources.ExternalLocationGrantPrivilege INPUT
resources.external_locations.*.grants[*].privileges[*] resources.ExternalLocationGrantPrivilege INPUT
resources.external_locations.*.grants[*].privileges []catalog.Privilege INPUT
resources.external_locations.*.grants[*].privileges[*] catalog.Privilege INPUT
resources.external_locations.*.id string INPUT
resources.external_locations.*.isolation_mode catalog.IsolationMode REMOTE
resources.external_locations.*.lifecycle resources.Lifecycle INPUT
Expand All @@ -729,8 +729,8 @@ resources.external_locations.*.updated_at int64 REMOTE
resources.external_locations.*.updated_by string REMOTE
resources.external_locations.*.url string ALL
resources.external_locations.*.grants.full_name string ALL
resources.external_locations.*.grants.grants []dresources.GrantAssignment ALL
resources.external_locations.*.grants.grants[*] dresources.GrantAssignment ALL
resources.external_locations.*.grants.grants []catalog.PrivilegeAssignment ALL
resources.external_locations.*.grants.grants[*] catalog.PrivilegeAssignment ALL
resources.external_locations.*.grants.grants[*].principal string ALL
resources.external_locations.*.grants.grants[*].privileges []catalog.Privilege ALL
resources.external_locations.*.grants.grants[*].privileges[*] catalog.Privilege ALL
Expand Down Expand Up @@ -2748,11 +2748,11 @@ resources.registered_models.*.comment string ALL
resources.registered_models.*.created_at int64 ALL
resources.registered_models.*.created_by string ALL
resources.registered_models.*.full_name string ALL
resources.registered_models.*.grants []resources.Grant INPUT
resources.registered_models.*.grants[*] resources.Grant INPUT
resources.registered_models.*.grants []catalog.PrivilegeAssignment INPUT
resources.registered_models.*.grants[*] catalog.PrivilegeAssignment INPUT
resources.registered_models.*.grants[*].principal string INPUT
resources.registered_models.*.grants[*].privileges []string INPUT
resources.registered_models.*.grants[*].privileges[*] string INPUT
resources.registered_models.*.grants[*].privileges []catalog.Privilege INPUT
resources.registered_models.*.grants[*].privileges[*] catalog.Privilege INPUT
resources.registered_models.*.id string INPUT
resources.registered_models.*.lifecycle resources.Lifecycle INPUT
resources.registered_models.*.lifecycle.prevent_destroy bool INPUT
Expand All @@ -2766,8 +2766,8 @@ resources.registered_models.*.updated_at int64 ALL
resources.registered_models.*.updated_by string ALL
resources.registered_models.*.url string INPUT
resources.registered_models.*.grants.full_name string ALL
resources.registered_models.*.grants.grants []dresources.GrantAssignment ALL
resources.registered_models.*.grants.grants[*] dresources.GrantAssignment ALL
resources.registered_models.*.grants.grants []catalog.PrivilegeAssignment ALL
resources.registered_models.*.grants.grants[*] catalog.PrivilegeAssignment ALL
resources.registered_models.*.grants.grants[*].principal string ALL
resources.registered_models.*.grants.grants[*].privileges []catalog.Privilege ALL
resources.registered_models.*.grants.grants[*].privileges[*] catalog.Privilege ALL
Expand All @@ -2784,11 +2784,11 @@ resources.schemas.*.effective_predictive_optimization_flag.inherited_from_type c
resources.schemas.*.effective_predictive_optimization_flag.value catalog.EnablePredictiveOptimization REMOTE
resources.schemas.*.enable_predictive_optimization catalog.EnablePredictiveOptimization REMOTE
resources.schemas.*.full_name string REMOTE
resources.schemas.*.grants []resources.SchemaGrant INPUT
resources.schemas.*.grants[*] resources.SchemaGrant INPUT
resources.schemas.*.grants []catalog.PrivilegeAssignment INPUT
resources.schemas.*.grants[*] catalog.PrivilegeAssignment INPUT
resources.schemas.*.grants[*].principal string INPUT
resources.schemas.*.grants[*].privileges []resources.SchemaGrantPrivilege INPUT
resources.schemas.*.grants[*].privileges[*] resources.SchemaGrantPrivilege INPUT
resources.schemas.*.grants[*].privileges []catalog.Privilege INPUT
resources.schemas.*.grants[*].privileges[*] catalog.Privilege INPUT
resources.schemas.*.id string INPUT
resources.schemas.*.lifecycle resources.Lifecycle INPUT
resources.schemas.*.lifecycle.prevent_destroy bool INPUT
Expand All @@ -2805,8 +2805,8 @@ resources.schemas.*.updated_at int64 REMOTE
resources.schemas.*.updated_by string REMOTE
resources.schemas.*.url string INPUT
resources.schemas.*.grants.full_name string ALL
resources.schemas.*.grants.grants []dresources.GrantAssignment ALL
resources.schemas.*.grants.grants[*] dresources.GrantAssignment ALL
resources.schemas.*.grants.grants []catalog.PrivilegeAssignment ALL
resources.schemas.*.grants.grants[*] catalog.PrivilegeAssignment ALL
resources.schemas.*.grants.grants[*].principal string ALL
resources.schemas.*.grants.grants[*].privileges []catalog.Privilege ALL
resources.schemas.*.grants.grants[*].privileges[*] catalog.Privilege ALL
Expand Down Expand Up @@ -2970,11 +2970,11 @@ resources.volumes.*.encryption_details.sse_encryption_details *catalog.SseEncryp
resources.volumes.*.encryption_details.sse_encryption_details.algorithm catalog.SseEncryptionDetailsAlgorithm REMOTE
resources.volumes.*.encryption_details.sse_encryption_details.aws_kms_key_arn string REMOTE
resources.volumes.*.full_name string REMOTE
resources.volumes.*.grants []resources.VolumeGrant INPUT
resources.volumes.*.grants[*] resources.VolumeGrant INPUT
resources.volumes.*.grants []catalog.PrivilegeAssignment INPUT
resources.volumes.*.grants[*] catalog.PrivilegeAssignment INPUT
resources.volumes.*.grants[*].principal string INPUT
resources.volumes.*.grants[*].privileges []resources.VolumeGrantPrivilege INPUT
resources.volumes.*.grants[*].privileges[*] resources.VolumeGrantPrivilege INPUT
resources.volumes.*.grants[*].privileges []catalog.Privilege INPUT
resources.volumes.*.grants[*].privileges[*] catalog.Privilege INPUT
resources.volumes.*.id string INPUT
resources.volumes.*.lifecycle resources.Lifecycle INPUT
resources.volumes.*.lifecycle.prevent_destroy bool INPUT
Expand All @@ -2990,8 +2990,8 @@ resources.volumes.*.url string INPUT
resources.volumes.*.volume_id string REMOTE
resources.volumes.*.volume_type catalog.VolumeType ALL
resources.volumes.*.grants.full_name string ALL
resources.volumes.*.grants.grants []dresources.GrantAssignment ALL
resources.volumes.*.grants.grants[*] dresources.GrantAssignment ALL
resources.volumes.*.grants.grants []catalog.PrivilegeAssignment ALL
resources.volumes.*.grants.grants[*] catalog.PrivilegeAssignment ALL
resources.volumes.*.grants.grants[*].principal string ALL
resources.volumes.*.grants.grants[*].privileges []catalog.Privilege ALL
resources.volumes.*.grants.grants[*].privileges[*] catalog.Privilege ALL
Expand Down
71 changes: 1 addition & 70 deletions bundle/config/resources/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,81 +13,12 @@ import (
"github.com/databricks/cli/libs/log"
)

type CatalogGrantPrivilege string

const (
CatalogGrantPrivilegeAllPrivileges CatalogGrantPrivilege = "ALL_PRIVILEGES"
CatalogGrantPrivilegeApplyTag CatalogGrantPrivilege = "APPLY_TAG"
CatalogGrantPrivilegeCreateConnection CatalogGrantPrivilege = "CREATE_CONNECTION"
CatalogGrantPrivilegeCreateExternalLocation CatalogGrantPrivilege = "CREATE_EXTERNAL_LOCATION"
CatalogGrantPrivilegeCreateExternalTable CatalogGrantPrivilege = "CREATE_EXTERNAL_TABLE"
CatalogGrantPrivilegeCreateExternalVolume CatalogGrantPrivilege = "CREATE_EXTERNAL_VOLUME"
CatalogGrantPrivilegeCreateForeignCatalog CatalogGrantPrivilege = "CREATE_FOREIGN_CATALOG"
CatalogGrantPrivilegeCreateFunction CatalogGrantPrivilege = "CREATE_FUNCTION"
CatalogGrantPrivilegeCreateManagedStorage CatalogGrantPrivilege = "CREATE_MANAGED_STORAGE"
CatalogGrantPrivilegeCreateMaterializedView CatalogGrantPrivilege = "CREATE_MATERIALIZED_VIEW"
CatalogGrantPrivilegeCreateModel CatalogGrantPrivilege = "CREATE_MODEL"
CatalogGrantPrivilegeCreateSchema CatalogGrantPrivilege = "CREATE_SCHEMA"
CatalogGrantPrivilegeCreateStorageCredential CatalogGrantPrivilege = "CREATE_STORAGE_CREDENTIAL"
CatalogGrantPrivilegeCreateTable CatalogGrantPrivilege = "CREATE_TABLE"
CatalogGrantPrivilegeCreateVolume CatalogGrantPrivilege = "CREATE_VOLUME"
CatalogGrantPrivilegeExecute CatalogGrantPrivilege = "EXECUTE"
CatalogGrantPrivilegeManage CatalogGrantPrivilege = "MANAGE"
CatalogGrantPrivilegeModify CatalogGrantPrivilege = "MODIFY"
CatalogGrantPrivilegeReadVolume CatalogGrantPrivilege = "READ_VOLUME"
CatalogGrantPrivilegeRefresh CatalogGrantPrivilege = "REFRESH"
CatalogGrantPrivilegeSelect CatalogGrantPrivilege = "SELECT"
CatalogGrantPrivilegeUseCatalog CatalogGrantPrivilege = "USE_CATALOG"
CatalogGrantPrivilegeUseConnection CatalogGrantPrivilege = "USE_CONNECTION"
CatalogGrantPrivilegeUseSchema CatalogGrantPrivilege = "USE_SCHEMA"
CatalogGrantPrivilegeWriteVolume CatalogGrantPrivilege = "WRITE_VOLUME"
)

// Values returns all valid CatalogGrantPrivilege values
func (CatalogGrantPrivilege) Values() []CatalogGrantPrivilege {
return []CatalogGrantPrivilege{
CatalogGrantPrivilegeAllPrivileges,
CatalogGrantPrivilegeApplyTag,
CatalogGrantPrivilegeCreateConnection,
CatalogGrantPrivilegeCreateExternalLocation,
CatalogGrantPrivilegeCreateExternalTable,
CatalogGrantPrivilegeCreateExternalVolume,
CatalogGrantPrivilegeCreateForeignCatalog,
CatalogGrantPrivilegeCreateFunction,
CatalogGrantPrivilegeCreateManagedStorage,
CatalogGrantPrivilegeCreateMaterializedView,
CatalogGrantPrivilegeCreateModel,
CatalogGrantPrivilegeCreateSchema,
CatalogGrantPrivilegeCreateStorageCredential,
CatalogGrantPrivilegeCreateTable,
CatalogGrantPrivilegeCreateVolume,
CatalogGrantPrivilegeExecute,
CatalogGrantPrivilegeManage,
CatalogGrantPrivilegeModify,
CatalogGrantPrivilegeReadVolume,
CatalogGrantPrivilegeRefresh,
CatalogGrantPrivilegeSelect,
CatalogGrantPrivilegeUseCatalog,
CatalogGrantPrivilegeUseConnection,
CatalogGrantPrivilegeUseSchema,
CatalogGrantPrivilegeWriteVolume,
}
}

// CatalogGrant holds the grant level settings for a single principal in Unity Catalog.
// Multiple of these can be defined on any catalog.
type CatalogGrant struct {
Privileges []CatalogGrantPrivilege `json:"privileges"`

Principal string `json:"principal"`
}

type Catalog struct {
BaseResource
catalog.CreateCatalog

// List of grants to apply on this catalog.
Grants []CatalogGrant `json:"grants,omitempty"`
Grants []catalog.PrivilegeAssignment `json:"grants,omitempty"`
}

func (c *Catalog) Exists(ctx context.Context, w *databricks.WorkspaceClient, name string) (bool, error) {
Expand Down
39 changes: 1 addition & 38 deletions bundle/config/resources/external_location.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,6 @@ import (
"github.com/databricks/cli/libs/log"
)

type ExternalLocationGrantPrivilege string

const (
ExternalLocationGrantPrivilegeAllPrivileges ExternalLocationGrantPrivilege = "ALL_PRIVILEGES"
ExternalLocationGrantPrivilegeCreateExternalTable ExternalLocationGrantPrivilege = "CREATE_EXTERNAL_TABLE"
ExternalLocationGrantPrivilegeCreateExternalVolume ExternalLocationGrantPrivilege = "CREATE_EXTERNAL_VOLUME"
ExternalLocationGrantPrivilegeCreateManagedStorage ExternalLocationGrantPrivilege = "CREATE_MANAGED_STORAGE"
ExternalLocationGrantPrivilegeCreateTable ExternalLocationGrantPrivilege = "CREATE_TABLE"
ExternalLocationGrantPrivilegeCreateVolume ExternalLocationGrantPrivilege = "CREATE_VOLUME"
ExternalLocationGrantPrivilegeManage ExternalLocationGrantPrivilege = "MANAGE"
ExternalLocationGrantPrivilegeReadFiles ExternalLocationGrantPrivilege = "READ_FILES"
ExternalLocationGrantPrivilegeWriteFiles ExternalLocationGrantPrivilege = "WRITE_FILES"
)

// Values returns all valid ExternalLocationGrantPrivilege values
func (ExternalLocationGrantPrivilege) Values() []ExternalLocationGrantPrivilege {
return []ExternalLocationGrantPrivilege{
ExternalLocationGrantPrivilegeAllPrivileges,
ExternalLocationGrantPrivilegeCreateExternalTable,
ExternalLocationGrantPrivilegeCreateExternalVolume,
ExternalLocationGrantPrivilegeCreateManagedStorage,
ExternalLocationGrantPrivilegeCreateTable,
ExternalLocationGrantPrivilegeCreateVolume,
ExternalLocationGrantPrivilegeManage,
ExternalLocationGrantPrivilegeReadFiles,
ExternalLocationGrantPrivilegeWriteFiles,
}
}

// ExternalLocationGrant holds the grant level settings for a single principal in Unity Catalog.
// Multiple of these can be defined on any external location.
type ExternalLocationGrant struct {
Privileges []ExternalLocationGrantPrivilege `json:"privileges"`

Principal string `json:"principal"`
}

type ExternalLocation struct {
// Manually include BaseResource fields to avoid URL field conflict
ID string `json:"id,omitempty" bundle:"readonly"`
Expand All @@ -59,7 +22,7 @@ type ExternalLocation struct {
catalog.CreateExternalLocation

// List of grants to apply on this external location.
Grants []ExternalLocationGrant `json:"grants,omitempty"`
Grants []catalog.PrivilegeAssignment `json:"grants,omitempty"`
}

func (e *ExternalLocation) Exists(ctx context.Context, w *databricks.WorkspaceClient, name string) (bool, error) {
Expand Down
Loading