diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index 60149ed865..f0c17ef7c5 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -5,6 +5,7 @@ ### CLI ### Bundles +* Modify grants to use SDK types ([#4666](https://github.com/databricks/cli/pull/4666)) ### Dependency updates diff --git a/acceptance/bundle/python/grants-aliases/databricks.yml b/acceptance/bundle/python/grants-aliases/databricks.yml new file mode 100644 index 0000000000..5cf3921b62 --- /dev/null +++ b/acceptance/bundle/python/grants-aliases/databricks.yml @@ -0,0 +1,9 @@ +bundle: + name: my_project + +sync: {paths: []} # don't need to copy files + +experimental: + python: + resources: + - "resources:load_resources" diff --git a/acceptance/bundle/python/grants-aliases/out.test.toml b/acceptance/bundle/python/grants-aliases/out.test.toml new file mode 100644 index 0000000000..0f245f65d5 --- /dev/null +++ b/acceptance/bundle/python/grants-aliases/out.test.toml @@ -0,0 +1,6 @@ +Local = true +Cloud = false + +[EnvMatrix] + DATABRICKS_BUNDLE_ENGINE = ["terraform", "direct"] + UV_ARGS = ["--with-requirements requirements-latest.txt --no-cache"] diff --git a/acceptance/bundle/python/grants-aliases/output.txt b/acceptance/bundle/python/grants-aliases/output.txt new file mode 100644 index 0000000000..06c25f7832 --- /dev/null +++ b/acceptance/bundle/python/grants-aliases/output.txt @@ -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" + } + } + } +} diff --git a/acceptance/bundle/python/grants-aliases/resources.py b/acceptance/bundle/python/grants-aliases/resources.py new file mode 100644 index 0000000000..deb53d964e --- /dev/null +++ b/acceptance/bundle/python/grants-aliases/resources.py @@ -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 diff --git a/acceptance/bundle/python/grants-aliases/script b/acceptance/bundle/python/grants-aliases/script new file mode 100644 index 0000000000..c94fd42a0c --- /dev/null +++ b/acceptance/bundle/python/grants-aliases/script @@ -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__ diff --git a/acceptance/bundle/python/grants-aliases/test.toml b/acceptance/bundle/python/grants-aliases/test.toml new file mode 100644 index 0000000000..81f3b9e2d7 --- /dev/null +++ b/acceptance/bundle/python/grants-aliases/test.toml @@ -0,0 +1,7 @@ +Local = true +Cloud = false # tests don't interact with APIs + +[EnvMatrix] +UV_ARGS = [ + "--with-requirements requirements-latest.txt --no-cache", +] diff --git a/acceptance/bundle/refschema/out.fields.txt b/acceptance/bundle/refschema/out.fields.txt index f401945572..0d57557d8d 100644 --- a/acceptance/bundle/refschema/out.fields.txt +++ b/acceptance/bundle/refschema/out.fields.txt @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/bundle/config/resources/catalog.go b/bundle/config/resources/catalog.go index 94ede64a55..d558f127f5 100644 --- a/bundle/config/resources/catalog.go +++ b/bundle/config/resources/catalog.go @@ -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) { diff --git a/bundle/config/resources/external_location.go b/bundle/config/resources/external_location.go index a44e9d7707..29cb5469d2 100644 --- a/bundle/config/resources/external_location.go +++ b/bundle/config/resources/external_location.go @@ -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"` @@ -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) { diff --git a/bundle/config/resources/grant.go b/bundle/config/resources/grant.go deleted file mode 100644 index f0ecd87674..0000000000 --- a/bundle/config/resources/grant.go +++ /dev/null @@ -1,9 +0,0 @@ -package resources - -// Grant holds the grant level settings for a single principal in Unity Catalog. -// Multiple of these can be defined on any Unity Catalog resource. -type Grant struct { - Privileges []string `json:"privileges"` - - Principal string `json:"principal"` -} diff --git a/bundle/config/resources/registered_model.go b/bundle/config/resources/registered_model.go index c8d82d08f1..c51450bf74 100644 --- a/bundle/config/resources/registered_model.go +++ b/bundle/config/resources/registered_model.go @@ -18,9 +18,8 @@ type RegisteredModel struct { // to a HCL representation for CRUD catalog.CreateRegisteredModelRequest - // This is a resource agnostic implementation of grants. - // Implementation could be different based on the resource type. - Grants []Grant `json:"grants,omitempty"` + // List of grants to apply on this registered model. + Grants []catalog.PrivilegeAssignment `json:"grants,omitempty"` } func (s *RegisteredModel) UnmarshalJSON(b []byte) error { diff --git a/bundle/config/resources/schema.go b/bundle/config/resources/schema.go index 124b1d940b..6cf4727279 100644 --- a/bundle/config/resources/schema.go +++ b/bundle/config/resources/schema.go @@ -14,62 +14,11 @@ import ( "github.com/databricks/databricks-sdk-go/service/catalog" ) -type SchemaGrantPrivilege string - -const ( - SchemaGrantPrivilegeAllPrivileges SchemaGrantPrivilege = "ALL_PRIVILEGES" - SchemaGrantPrivilegeApplyTag SchemaGrantPrivilege = "APPLY_TAG" - SchemaGrantPrivilegeCreateFunction SchemaGrantPrivilege = "CREATE_FUNCTION" - SchemaGrantPrivilegeCreateMaterializedView SchemaGrantPrivilege = "CREATE_MATERIALIZED_VIEW" - SchemaGrantPrivilegeCreateModel SchemaGrantPrivilege = "CREATE_MODEL" - SchemaGrantPrivilegeCreateTable SchemaGrantPrivilege = "CREATE_TABLE" - SchemaGrantPrivilegeCreateVolume SchemaGrantPrivilege = "CREATE_VOLUME" - SchemaGrantPrivilegeExecute SchemaGrantPrivilege = "EXECUTE" - SchemaGrantPrivilegeExternalUseSchema SchemaGrantPrivilege = "EXTERNAL_USE_SCHEMA" - SchemaGrantPrivilegeManage SchemaGrantPrivilege = "MANAGE" - SchemaGrantPrivilegeModify SchemaGrantPrivilege = "MODIFY" - SchemaGrantPrivilegeReadVolume SchemaGrantPrivilege = "READ_VOLUME" - SchemaGrantPrivilegeRefresh SchemaGrantPrivilege = "REFRESH" - SchemaGrantPrivilegeSelect SchemaGrantPrivilege = "SELECT" - SchemaGrantPrivilegeUseSchema SchemaGrantPrivilege = "USE_SCHEMA" - SchemaGrantPrivilegeWriteVolume SchemaGrantPrivilege = "WRITE_VOLUME" -) - -// Values returns all valid SchemaGrantPrivilege values -func (SchemaGrantPrivilege) Values() []SchemaGrantPrivilege { - return []SchemaGrantPrivilege{ - SchemaGrantPrivilegeAllPrivileges, - SchemaGrantPrivilegeApplyTag, - SchemaGrantPrivilegeCreateFunction, - SchemaGrantPrivilegeCreateMaterializedView, - SchemaGrantPrivilegeCreateModel, - SchemaGrantPrivilegeCreateTable, - SchemaGrantPrivilegeCreateVolume, - SchemaGrantPrivilegeExecute, - SchemaGrantPrivilegeExternalUseSchema, - SchemaGrantPrivilegeManage, - SchemaGrantPrivilegeModify, - SchemaGrantPrivilegeReadVolume, - SchemaGrantPrivilegeRefresh, - SchemaGrantPrivilegeSelect, - SchemaGrantPrivilegeUseSchema, - SchemaGrantPrivilegeWriteVolume, - } -} - -// SchemaGrant holds the grant level settings for a single principal in Unity Catalog. -// Multiple of these can be defined on any schema. -type SchemaGrant struct { - Privileges []SchemaGrantPrivilege `json:"privileges"` - - Principal string `json:"principal"` -} - type Schema struct { BaseResource catalog.CreateSchema // List of grants to apply on this schema. - Grants []SchemaGrant `json:"grants,omitempty"` + Grants []catalog.PrivilegeAssignment `json:"grants,omitempty"` } func (s *Schema) Exists(ctx context.Context, w *databricks.WorkspaceClient, fullName string) (bool, error) { diff --git a/bundle/config/resources/schema_test.go b/bundle/config/resources/schema_test.go index bb3d313fb2..55537062d5 100644 --- a/bundle/config/resources/schema_test.go +++ b/bundle/config/resources/schema_test.go @@ -1,14 +1,10 @@ package resources import ( - "fmt" - "sort" "testing" "github.com/databricks/databricks-sdk-go/apierr" "github.com/databricks/databricks-sdk-go/experimental/mocks" - "github.com/databricks/databricks-sdk-go/service/catalog" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) @@ -27,141 +23,3 @@ func TestSchemaNotFound(t *testing.T) { require.Falsef(t, exists, "Exists should return false when getting a 404 response from Workspace") require.NoErrorf(t, err, "Exists should not return an error when getting a 404 response from Workspace") } - -func TestSchemaGrantPrivilegesExhaustive(t *testing.T) { - // Privileges that are NOT valid for schemas and should be skipped. - // These are valid for other securable types (catalogs, connections, etc.) - // Source: https://docs.databricks.com/en/data-governance/unity-catalog/manage-privileges/privileges.html - skippedPrivileges := map[catalog.Privilege]string{ - // Catalog-level privileges - catalog.PrivilegeCreateCatalog: "catalog-level", - catalog.PrivilegeCreateSchema: "catalog-level", - catalog.PrivilegeUseCatalog: "catalog-level", - - // Connection-level privileges - catalog.PrivilegeCreateConnection: "connection-level", - catalog.PrivilegeUseConnection: "connection-level", - - // Storage-level privileges - catalog.PrivilegeCreateExternalLocation: "storage-level", - catalog.PrivilegeCreateExternalTable: "storage-level", - catalog.PrivilegeCreateExternalVolume: "storage-level", - catalog.PrivilegeCreateManagedStorage: "storage-level", - catalog.PrivilegeCreateStorageCredential: "storage-level", - catalog.PrivilegeReadFiles: "storage-level", - catalog.PrivilegeReadPrivateFiles: "storage-level", - catalog.PrivilegeWriteFiles: "storage-level", - catalog.PrivilegeWritePrivateFiles: "storage-level", - - // Metastore-level privileges - catalog.PrivilegeCreateProvider: "metastore-level", - catalog.PrivilegeCreateRecipient: "metastore-level", - catalog.PrivilegeCreateShare: "metastore-level", - catalog.PrivilegeManageAllowlist: "metastore-level", - catalog.PrivilegeUseProvider: "metastore-level", - catalog.PrivilegeUseRecipient: "metastore-level", - catalog.PrivilegeUseMarketplaceAssets: "metastore-level", - catalog.PrivilegeCreateServiceCredential: "metastore-level", - - // Share-level privileges - catalog.PrivilegeSetSharePermission: "share-level", - catalog.PrivilegeUseShare: "share-level", - - // Clean room-level privileges - catalog.PrivilegeCreateCleanRoom: "clean-room-level", - catalog.PrivilegeExecuteCleanRoomTask: "clean-room-level", - catalog.PrivilegeModifyCleanRoom: "clean-room-level", - - // Foreign securable privileges - catalog.PrivilegeCreateForeignCatalog: "foreign-securable", - catalog.PrivilegeCreateForeignSecurable: "foreign-securable", - - // Table/view-level privileges (not directly grantable on schema) - catalog.PrivilegeCreateView: "table-level", - - // Generic privileges that don't apply to schemas - catalog.PrivilegeAccess: "generic", - catalog.PrivilegeBrowse: "generic", - catalog.PrivilegeCreate: "generic", - catalog.PrivilegeUsage: "generic", - } - - // Get all SDK privileges dynamically - var p catalog.Privilege - sdkPrivileges := p.Values() - - // Get all privileges defined in our SchemaGrantPrivilege enum - definedPrivileges := SchemaGrantPrivilege("").Values() - definedPrivilegeMap := make(map[catalog.Privilege]bool) - for _, priv := range definedPrivileges { - definedPrivilegeMap[catalog.Privilege(priv)] = true - } - - // Build list of missing and unexpected privileges - var missingPrivileges []catalog.Privilege - var unexpectedPrivileges []catalog.Privilege - - // Check each SDK privilege - for _, sdkPriv := range sdkPrivileges { - isInDefined := definedPrivilegeMap[sdkPriv] - isInSkipList := skippedPrivileges[sdkPriv] != "" - - if !isInDefined && !isInSkipList { - // SDK has a privilege that we neither defined nor explicitly skipped - missingPrivileges = append(missingPrivileges, sdkPriv) - } - - if isInDefined && isInSkipList { - // We defined a privilege that's in the skip list (contradiction) - unexpectedPrivileges = append(unexpectedPrivileges, sdkPriv) - } - } - - // Check for privileges we defined that don't exist in SDK - sdkPrivilegeMap := make(map[catalog.Privilege]bool) - for _, priv := range sdkPrivileges { - sdkPrivilegeMap[priv] = true - } - - var invalidPrivileges []SchemaGrantPrivilege - for _, definedPriv := range definedPrivileges { - if !sdkPrivilegeMap[catalog.Privilege(definedPriv)] { - invalidPrivileges = append(invalidPrivileges, definedPriv) - } - } - - // Report errors - if len(missingPrivileges) > 0 { - sort.Slice(missingPrivileges, func(i, j int) bool { - return missingPrivileges[i] < missingPrivileges[j] - }) - assert.Fail(t, fmt.Sprintf( - "Found %d SDK privilege(s) that are not in SchemaGrantPrivilege and not in skip list.\n"+ - "If these privileges are valid for schemas, add them to SchemaGrantPrivilege in schema.go.\n"+ - "If they are NOT valid for schemas, add them to skippedPrivileges in schema_test.go.\n"+ - "Missing privileges: %v", - len(missingPrivileges), missingPrivileges)) - } - - if len(unexpectedPrivileges) > 0 { - sort.Slice(unexpectedPrivileges, func(i, j int) bool { - return unexpectedPrivileges[i] < unexpectedPrivileges[j] - }) - assert.Fail(t, fmt.Sprintf( - "Found %d privilege(s) that are both defined in SchemaGrantPrivilege AND in skip list.\n"+ - "This is a contradiction - remove them from either SchemaGrantPrivilege or the skip list.\n"+ - "Conflicting privileges: %v", - len(unexpectedPrivileges), unexpectedPrivileges)) - } - - if len(invalidPrivileges) > 0 { - sort.Slice(invalidPrivileges, func(i, j int) bool { - return invalidPrivileges[i] < invalidPrivileges[j] - }) - assert.Fail(t, fmt.Sprintf( - "Found %d privilege(s) in SchemaGrantPrivilege that don't exist in the SDK.\n"+ - "Remove these from SchemaGrantPrivilege in schema.go.\n"+ - "Invalid privileges: %v", - len(invalidPrivileges), invalidPrivileges)) - } -} diff --git a/bundle/config/resources/volume.go b/bundle/config/resources/volume.go index 8c47a6afc4..112f502066 100644 --- a/bundle/config/resources/volume.go +++ b/bundle/config/resources/volume.go @@ -13,39 +13,12 @@ import ( "github.com/databricks/databricks-sdk-go/service/catalog" ) -type VolumeGrantPrivilege string - -const ( - VolumeGrantPrivilegeAllPrivileges VolumeGrantPrivilege = "ALL_PRIVILEGES" - VolumeGrantPrivilegeApplyTag VolumeGrantPrivilege = "APPLY_TAG" - VolumeGrantPrivilegeManage VolumeGrantPrivilege = "MANAGE" - VolumeGrantPrivilegeReadVolume VolumeGrantPrivilege = "READ_VOLUME" - VolumeGrantPrivilegeWriteVolume VolumeGrantPrivilege = "WRITE_VOLUME" -) - -// Values returns all valid VolumeGrantPrivilege values -func (VolumeGrantPrivilege) Values() []VolumeGrantPrivilege { - return []VolumeGrantPrivilege{ - VolumeGrantPrivilegeAllPrivileges, - VolumeGrantPrivilegeApplyTag, - VolumeGrantPrivilegeManage, - VolumeGrantPrivilegeReadVolume, - VolumeGrantPrivilegeWriteVolume, - } -} - -type VolumeGrant struct { - Privileges []VolumeGrantPrivilege `json:"privileges"` - - Principal string `json:"principal"` -} - type Volume struct { BaseResource catalog.CreateVolumeRequestContent // List of grants to apply on this volume. - Grants []VolumeGrant `json:"grants,omitempty"` + Grants []catalog.PrivilegeAssignment `json:"grants,omitempty"` } func (v *Volume) UnmarshalJSON(b []byte) error { diff --git a/bundle/deploy/terraform/convert_test.go b/bundle/deploy/terraform/convert_test.go index ffec1cb7b1..564340190d 100644 --- a/bundle/deploy/terraform/convert_test.go +++ b/bundle/deploy/terraform/convert_test.go @@ -543,9 +543,9 @@ func TestBundleToTerraformRegisteredModelGrants(t *testing.T) { CatalogName: "catalog", SchemaName: "schema", }, - Grants: []resources.Grant{ + Grants: []catalog.PrivilegeAssignment{ { - Privileges: []string{"EXECUTE"}, + Privileges: []catalog.Privilege{catalog.PrivilegeExecute}, Principal: "jane@doe.com", }, }, diff --git a/bundle/deploy/terraform/tfdyn/convert_grants_test.go b/bundle/deploy/terraform/tfdyn/convert_grants_test.go index 9717529a86..6019ab823d 100644 --- a/bundle/deploy/terraform/tfdyn/convert_grants_test.go +++ b/bundle/deploy/terraform/tfdyn/convert_grants_test.go @@ -7,19 +7,20 @@ import ( "github.com/databricks/cli/bundle/internal/tf/schema" "github.com/databricks/cli/libs/dyn" "github.com/databricks/cli/libs/dyn/convert" + "github.com/databricks/databricks-sdk-go/service/catalog" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestConvertGrants(t *testing.T) { src := resources.RegisteredModel{ - Grants: []resources.Grant{ + Grants: []catalog.PrivilegeAssignment{ { - Privileges: []string{"EXECUTE", "FOO"}, + Privileges: []catalog.Privilege{"EXECUTE", "FOO"}, Principal: "jane@doe.com", }, { - Privileges: []string{"EXECUTE", "BAR"}, + Privileges: []catalog.Privilege{"EXECUTE", "BAR"}, Principal: "spn", }, }, @@ -58,7 +59,7 @@ func TestConvertGrantsNil(t *testing.T) { func TestConvertGrantsEmpty(t *testing.T) { src := resources.RegisteredModel{ - Grants: []resources.Grant{}, + Grants: []catalog.PrivilegeAssignment{}, } vin, err := convert.FromTyped(src, dyn.NilValue) diff --git a/bundle/deploy/terraform/tfdyn/convert_registered_model_test.go b/bundle/deploy/terraform/tfdyn/convert_registered_model_test.go index 04bf331502..dab20f45eb 100644 --- a/bundle/deploy/terraform/tfdyn/convert_registered_model_test.go +++ b/bundle/deploy/terraform/tfdyn/convert_registered_model_test.go @@ -20,9 +20,9 @@ func TestConvertRegisteredModel(t *testing.T) { SchemaName: "schema", Comment: "comment", }, - Grants: []resources.Grant{ + Grants: []catalog.PrivilegeAssignment{ { - Privileges: []string{"EXECUTE"}, + Privileges: []catalog.Privilege{catalog.PrivilegeExecute}, Principal: "jane@doe.com", }, }, diff --git a/bundle/deploy/terraform/tfdyn/convert_schema_test.go b/bundle/deploy/terraform/tfdyn/convert_schema_test.go index ec738d3ef0..1d2431a5e1 100644 --- a/bundle/deploy/terraform/tfdyn/convert_schema_test.go +++ b/bundle/deploy/terraform/tfdyn/convert_schema_test.go @@ -24,18 +24,14 @@ func TestConvertSchema(t *testing.T) { }, StorageRoot: "root", }, - Grants: []resources.SchemaGrant{ + Grants: []catalog.PrivilegeAssignment{ { - Privileges: []resources.SchemaGrantPrivilege{ - resources.SchemaGrantPrivilegeExecute, - }, - Principal: "jack@gmail.com", + Privileges: []catalog.Privilege{catalog.PrivilegeExecute}, + Principal: "jack@gmail.com", }, { - Privileges: []resources.SchemaGrantPrivilege{ - resources.SchemaGrantPrivilegeSelect, - }, - Principal: "jane@gmail.com", + Privileges: []catalog.Privilege{catalog.PrivilegeSelect}, + Principal: "jane@gmail.com", }, }, } diff --git a/bundle/deploy/terraform/tfdyn/convert_volume_test.go b/bundle/deploy/terraform/tfdyn/convert_volume_test.go index 6eb344853d..bd8798780a 100644 --- a/bundle/deploy/terraform/tfdyn/convert_volume_test.go +++ b/bundle/deploy/terraform/tfdyn/convert_volume_test.go @@ -22,18 +22,14 @@ func TestConvertVolume(t *testing.T) { StorageLocation: "s3://bucket/path", VolumeType: "EXTERNAL", }, - Grants: []resources.VolumeGrant{ + Grants: []catalog.PrivilegeAssignment{ { - Privileges: []resources.VolumeGrantPrivilege{ - resources.VolumeGrantPrivilegeReadVolume, - }, - Principal: "jack@gmail.com", + Privileges: []catalog.Privilege{catalog.PrivilegeReadVolume}, + Principal: "jack@gmail.com", }, { - Privileges: []resources.VolumeGrantPrivilege{ - resources.VolumeGrantPrivilegeWriteVolume, - }, - Principal: "jane@gmail.com", + Privileges: []catalog.Privilege{catalog.PrivilegeWriteVolume}, + Principal: "jane@gmail.com", }, }, } diff --git a/bundle/direct/dresources/all_test.go b/bundle/direct/dresources/all_test.go index 124d9a4ec9..0c3d95da8a 100644 --- a/bundle/direct/dresources/all_test.go +++ b/bundle/direct/dresources/all_test.go @@ -509,7 +509,7 @@ var testDeps = map[string]prepareWorkspace{ return &GrantsState{ SecurableType: "catalog", FullName: "mycatalog", - Grants: []GrantAssignment{{ + Grants: []catalog.PrivilegeAssignment{{ Privileges: []catalog.Privilege{catalog.PrivilegeUseCatalog}, Principal: "user@example.com", }}, @@ -520,7 +520,7 @@ var testDeps = map[string]prepareWorkspace{ return &GrantsState{ SecurableType: "external_location", FullName: "myexternallocation", - Grants: []GrantAssignment{{ + Grants: []catalog.PrivilegeAssignment{{ Privileges: []catalog.Privilege{catalog.PrivilegeReadFiles}, Principal: "user@example.com", }}, @@ -531,7 +531,7 @@ var testDeps = map[string]prepareWorkspace{ return &GrantsState{ SecurableType: "schema", FullName: "main.myschema", - Grants: []GrantAssignment{{ + Grants: []catalog.PrivilegeAssignment{{ Privileges: []catalog.Privilege{catalog.PrivilegeCreateView}, Principal: "user@example.com", }}, @@ -542,7 +542,7 @@ var testDeps = map[string]prepareWorkspace{ return &GrantsState{ SecurableType: "volume", FullName: "main.myschema.myvolume", - Grants: []GrantAssignment{{ + Grants: []catalog.PrivilegeAssignment{{ Privileges: []catalog.Privilege{catalog.PrivilegeCreateView}, Principal: "user@example.com", }}, @@ -553,7 +553,7 @@ var testDeps = map[string]prepareWorkspace{ return &GrantsState{ SecurableType: "registered-model", FullName: "modelid", - Grants: []GrantAssignment{{ + Grants: []catalog.PrivilegeAssignment{{ Privileges: []catalog.Privilege{catalog.PrivilegeCreateView}, Principal: "user@example.com", }}, diff --git a/bundle/direct/dresources/grants.go b/bundle/direct/dresources/grants.go index 76e504e5a0..8c0989aa99 100644 --- a/bundle/direct/dresources/grants.go +++ b/bundle/direct/dresources/grants.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "reflect" "sort" "strings" @@ -21,15 +20,10 @@ var grantResourceToSecurableType = map[string]string{ "registered_models": "function", } -type GrantAssignment struct { - Principal string `json:"principal"` - Privileges []catalog.Privilege `json:"privileges,omitempty"` -} - type GrantsState struct { - SecurableType string `json:"securable_type"` - FullName string `json:"full_name"` - Grants []GrantAssignment `json:"grants,omitempty"` + SecurableType string `json:"securable_type"` + FullName string `json:"full_name"` + Grants []catalog.PrivilegeAssignment `json:"grants,omitempty"` } func PrepareGrantsInputConfig(inputConfig any, node string) (*structvar.StructVar, error) { @@ -48,59 +42,21 @@ func PrepareGrantsInputConfig(inputConfig any, node string) (*structvar.StructVa return nil, fmt.Errorf("unsupported grants resource type: %s", resourceType) } - rv := reflect.ValueOf(inputConfig) - if rv.Kind() != reflect.Ptr || rv.Elem().Kind() != reflect.Slice { - return nil, fmt.Errorf("inputConfig must be a pointer to a slice, got: %T", inputConfig) + grantsPtr, ok := inputConfig.(*[]catalog.PrivilegeAssignment) + if !ok { + return nil, fmt.Errorf("expected *[]catalog.PrivilegeAssignment, got %T", inputConfig) } - sliceValue := rv.Elem() - grants := make([]GrantAssignment, 0, sliceValue.Len()) - for i := range sliceValue.Len() { - elem := sliceValue.Index(i) - if elem.Kind() == reflect.Ptr { - elem = elem.Elem() - } - if elem.Kind() != reflect.Struct { - return nil, fmt.Errorf("grant element must be a struct, got %s", elem.Kind()) - } - - principalField := elem.FieldByName("Principal") - if !principalField.IsValid() { - return nil, errors.New("grant element missing Principal field") - } - principal := principalField.String() - - privilegesField := elem.FieldByName("Privileges") - if !privilegesField.IsValid() { - return nil, errors.New("grant element missing Privileges field") - } - if privilegesField.Kind() != reflect.Slice { - return nil, errors.New("grant Privileges field must be a slice") - } - - privileges := make([]catalog.Privilege, 0, privilegesField.Len()) - for j := range privilegesField.Len() { - item := privilegesField.Index(j) - if item.Kind() != reflect.String { - return nil, fmt.Errorf("privilege must be a string, got %s", item.Kind()) - } - privileges = append(privileges, catalog.Privilege(item.String())) - } - - // Backend sorts privileges, so we sort here as well. - sortPriviliges(privileges) - - grants = append(grants, GrantAssignment{ - Principal: principal, - Privileges: privileges, - }) + // Backend sorts privileges, so we sort here as well. + for i := range *grantsPtr { + sortPriviliges((*grantsPtr)[i].Privileges) } return &structvar.StructVar{ Value: &GrantsState{ SecurableType: securableType, FullName: "", - Grants: grants, + Grants: *grantsPtr, }, Refs: map[string]string{ "full_name": "${" + baseNode + ".id}", @@ -182,8 +138,8 @@ func (r *ResourceGrants) applyGrants(ctx context.Context, state *GrantsState) er return err } -func (r *ResourceGrants) listGrants(ctx context.Context, securableType, fullName string) ([]GrantAssignment, error) { - var assignments []GrantAssignment +func (r *ResourceGrants) listGrants(ctx context.Context, securableType, fullName string) ([]catalog.PrivilegeAssignment, error) { + var assignments []catalog.PrivilegeAssignment pageToken := "" for { resp, err := r.client.Grants.Get(ctx, catalog.GetGrantRequest{ @@ -203,9 +159,10 @@ func (r *ResourceGrants) listGrants(ctx context.Context, securableType, fullName } privs := make([]catalog.Privilege, len(assignment.Privileges)) copy(privs, assignment.Privileges) - assignments = append(assignments, GrantAssignment{ - Principal: assignment.Principal, - Privileges: privs, + assignments = append(assignments, catalog.PrivilegeAssignment{ + Principal: assignment.Principal, + Privileges: privs, + ForceSendFields: nil, }) } if resp.NextPageToken == "" { diff --git a/bundle/internal/schema/annotations.yml b/bundle/internal/schema/annotations.yml index 8b4817bd4f..e5b3ccd0dd 100644 --- a/bundle/internal/schema/annotations.yml +++ b/bundle/internal/schema/annotations.yml @@ -583,66 +583,6 @@ github.com/databricks/cli/bundle/config/resources.Catalog: "storage_root": "description": |- PLACEHOLDER -github.com/databricks/cli/bundle/config/resources.CatalogGrant: - "principal": - "description": |- - PLACEHOLDER - "privileges": - "description": |- - PLACEHOLDER -github.com/databricks/cli/bundle/config/resources.CatalogGrantPrivilege: - "_": - "enum": - - |- - ALL_PRIVILEGES - - |- - APPLY_TAG - - |- - CREATE_CONNECTION - - |- - CREATE_EXTERNAL_LOCATION - - |- - CREATE_EXTERNAL_TABLE - - |- - CREATE_EXTERNAL_VOLUME - - |- - CREATE_FOREIGN_CATALOG - - |- - CREATE_FUNCTION - - |- - CREATE_MANAGED_STORAGE - - |- - CREATE_MATERIALIZED_VIEW - - |- - CREATE_MODEL - - |- - CREATE_SCHEMA - - |- - CREATE_STORAGE_CREDENTIAL - - |- - CREATE_TABLE - - |- - CREATE_VOLUME - - |- - EXECUTE - - |- - MANAGE - - |- - MODIFY - - |- - READ_VOLUME - - |- - REFRESH - - |- - SELECT - - |- - USE_CATALOG - - |- - USE_CONNECTION - - |- - USE_SCHEMA - - |- - WRITE_VOLUME github.com/databricks/cli/bundle/config/resources.ClusterPermission: "group_name": "description": |- @@ -743,20 +683,6 @@ github.com/databricks/cli/bundle/config/resources.ExternalLocation: "url": "description": |- PLACEHOLDER -github.com/databricks/cli/bundle/config/resources.ExternalLocationGrant: - "principal": - "description": |- - PLACEHOLDER - "privileges": - "description": |- - PLACEHOLDER -github.com/databricks/cli/bundle/config/resources.Grant: - "principal": - "description": |- - The name of the principal that will be granted privileges - "privileges": - "description": |- - The privileges to grant to the specified entity github.com/databricks/cli/bundle/config/resources.JobPermission: "group_name": "description": |- @@ -991,13 +917,6 @@ github.com/databricks/cli/bundle/config/resources.PostgresProject: "update_time": "description": |- PLACEHOLDER -github.com/databricks/cli/bundle/config/resources.SchemaGrant: - "principal": - "description": |- - PLACEHOLDER - "privileges": - "description": |- - PLACEHOLDER github.com/databricks/cli/bundle/config/resources.SecretScope: "backend_type": "description": |- @@ -1065,13 +984,6 @@ github.com/databricks/cli/bundle/config/resources.SyncedDatabaseTable: "unity_catalog_provisioning_state": "description": |- PLACEHOLDER -github.com/databricks/cli/bundle/config/resources.VolumeGrant: - "principal": - "description": |- - PLACEHOLDER - "privileges": - "description": |- - PLACEHOLDER github.com/databricks/cli/bundle/config/variable.Lookup: "alert": "description": |- diff --git a/bundle/internal/schema/annotations_openapi.yml b/bundle/internal/schema/annotations_openapi.yml index d033809ef5..882f5c1cf2 100644 --- a/bundle/internal/schema/annotations_openapi.yml +++ b/bundle/internal/schema/annotations_openapi.yml @@ -1688,6 +1688,117 @@ github.com/databricks/databricks-sdk-go/service/catalog.MonitorTimeSeries: "timestamp_col": "description": |- Column for the timestamp. +github.com/databricks/databricks-sdk-go/service/catalog.Privilege: + "_": + "enum": + - |- + SELECT + - |- + READ_PRIVATE_FILES + - |- + WRITE_PRIVATE_FILES + - |- + CREATE + - |- + USAGE + - |- + USE_CATALOG + - |- + USE_SCHEMA + - |- + CREATE_SCHEMA + - |- + CREATE_VIEW + - |- + CREATE_EXTERNAL_TABLE + - |- + CREATE_MATERIALIZED_VIEW + - |- + CREATE_FUNCTION + - |- + CREATE_MODEL + - |- + CREATE_CATALOG + - |- + CREATE_MANAGED_STORAGE + - |- + CREATE_EXTERNAL_LOCATION + - |- + CREATE_STORAGE_CREDENTIAL + - |- + CREATE_SERVICE_CREDENTIAL + - |- + ACCESS + - |- + CREATE_SHARE + - |- + CREATE_RECIPIENT + - |- + CREATE_PROVIDER + - |- + USE_SHARE + - |- + USE_RECIPIENT + - |- + USE_PROVIDER + - |- + USE_MARKETPLACE_ASSETS + - |- + SET_SHARE_PERMISSION + - |- + MODIFY + - |- + REFRESH + - |- + EXECUTE + - |- + READ_FILES + - |- + WRITE_FILES + - |- + CREATE_TABLE + - |- + ALL_PRIVILEGES + - |- + CREATE_CONNECTION + - |- + USE_CONNECTION + - |- + APPLY_TAG + - |- + CREATE_FOREIGN_CATALOG + - |- + CREATE_FOREIGN_SECURABLE + - |- + MANAGE_ALLOWLIST + - |- + CREATE_VOLUME + - |- + CREATE_EXTERNAL_VOLUME + - |- + READ_VOLUME + - |- + WRITE_VOLUME + - |- + MANAGE + - |- + BROWSE + - |- + CREATE_CLEAN_ROOM + - |- + MODIFY_CLEAN_ROOM + - |- + EXECUTE_CLEAN_ROOM_TASK + - |- + EXTERNAL_USE_SCHEMA +github.com/databricks/databricks-sdk-go/service/catalog.PrivilegeAssignment: + "principal": + "description": |- + The principal (user email address or group name). + For deleted principals, `principal` is empty while `principal_id` is populated. + "privileges": + "description": |- + The privileges assigned to the principal. github.com/databricks/databricks-sdk-go/service/catalog.RegisteredModelAlias: "alias_name": "description": |- diff --git a/bundle/internal/schema/annotations_openapi_overrides.yml b/bundle/internal/schema/annotations_openapi_overrides.yml index baf54f2af6..4aaab347e0 100644 --- a/bundle/internal/schema/annotations_openapi_overrides.yml +++ b/bundle/internal/schema/annotations_openapi_overrides.yml @@ -277,29 +277,6 @@ github.com/databricks/cli/bundle/config/resources.ExternalLocation: "lifecycle": "description": |- PLACEHOLDER -github.com/databricks/cli/bundle/config/resources.ExternalLocationGrantPrivilege: - "_": - "description": |- - Privilege to grant on an external location - "enum": - - |- - ALL_PRIVILEGES - - |- - CREATE_EXTERNAL_TABLE - - |- - CREATE_EXTERNAL_VOLUME - - |- - CREATE_MANAGED_STORAGE - - |- - CREATE_TABLE - - |- - CREATE_VOLUME - - |- - MANAGE - - |- - READ_FILES - - |- - WRITE_FILES github.com/databricks/cli/bundle/config/resources.Job: "_": "markdown_description": |- @@ -634,41 +611,6 @@ github.com/databricks/cli/bundle/config/resources.Schema: "properties": "description": |- PLACEHOLDER -github.com/databricks/cli/bundle/config/resources.SchemaGrantPrivilege: - "_": - "enum": - - |- - ALL_PRIVILEGES - - |- - APPLY_TAG - - |- - CREATE_FUNCTION - - |- - CREATE_MATERIALIZED_VIEW - - |- - CREATE_MODEL - - |- - CREATE_TABLE - - |- - CREATE_VOLUME - - |- - EXECUTE - - |- - EXTERNAL_USE_SCHEMA - - |- - MANAGE - - |- - MODIFY - - |- - READ_VOLUME - - |- - REFRESH - - |- - SELECT - - |- - USE_SCHEMA - - |- - WRITE_VOLUME github.com/databricks/cli/bundle/config/resources.SecretScopePermissionLevel: "_": "enum": @@ -741,19 +683,6 @@ github.com/databricks/cli/bundle/config/resources.Volume: "volume_type": "description": |- PLACEHOLDER -github.com/databricks/cli/bundle/config/resources.VolumeGrantPrivilege: - "_": - "enum": - - |- - ALL_PRIVILEGES - - |- - APPLY_TAG - - |- - MANAGE - - |- - READ_VOLUME - - |- - WRITE_VOLUME github.com/databricks/databricks-sdk-go/service/apps.AppDeployment: "create_time": "description": |- diff --git a/bundle/internal/schema/testdata/pass/ml.yml b/bundle/internal/schema/testdata/pass/ml.yml index 3c0c39a0d2..d2885b6412 100644 --- a/bundle/internal/schema/testdata/pass/ml.yml +++ b/bundle/internal/schema/testdata/pass/ml.yml @@ -65,4 +65,4 @@ resources: - principal: abcd privileges: - SELECT - - INSERT + - MODIFY diff --git a/bundle/internal/validation/generated/enum_fields.go b/bundle/internal/validation/generated/enum_fields.go index c1ea107de4..81b2fdb284 100644 --- a/bundle/internal/validation/generated/enum_fields.go +++ b/bundle/internal/validation/generated/enum_fields.go @@ -33,7 +33,7 @@ var EnumFields = map[string][]string{ "resources.apps.*.resources[*].uc_securable.permission": {"EXECUTE", "MODIFY", "READ_VOLUME", "SELECT", "USE_CONNECTION", "WRITE_VOLUME"}, "resources.apps.*.resources[*].uc_securable.securable_type": {"CONNECTION", "FUNCTION", "TABLE", "VOLUME"}, - "resources.catalogs.*.grants[*].privileges[*]": {"ALL_PRIVILEGES", "APPLY_TAG", "CREATE_CONNECTION", "CREATE_EXTERNAL_LOCATION", "CREATE_EXTERNAL_TABLE", "CREATE_EXTERNAL_VOLUME", "CREATE_FOREIGN_CATALOG", "CREATE_FUNCTION", "CREATE_MANAGED_STORAGE", "CREATE_MATERIALIZED_VIEW", "CREATE_MODEL", "CREATE_SCHEMA", "CREATE_STORAGE_CREDENTIAL", "CREATE_TABLE", "CREATE_VOLUME", "EXECUTE", "MANAGE", "MODIFY", "READ_VOLUME", "REFRESH", "SELECT", "USE_CATALOG", "USE_CONNECTION", "USE_SCHEMA", "WRITE_VOLUME"}, + "resources.catalogs.*.grants[*].privileges[*]": {"ACCESS", "ALL_PRIVILEGES", "APPLY_TAG", "BROWSE", "CREATE", "CREATE_CATALOG", "CREATE_CLEAN_ROOM", "CREATE_CONNECTION", "CREATE_EXTERNAL_LOCATION", "CREATE_EXTERNAL_TABLE", "CREATE_EXTERNAL_VOLUME", "CREATE_FOREIGN_CATALOG", "CREATE_FOREIGN_SECURABLE", "CREATE_FUNCTION", "CREATE_MANAGED_STORAGE", "CREATE_MATERIALIZED_VIEW", "CREATE_MODEL", "CREATE_PROVIDER", "CREATE_RECIPIENT", "CREATE_SCHEMA", "CREATE_SERVICE_CREDENTIAL", "CREATE_SHARE", "CREATE_STORAGE_CREDENTIAL", "CREATE_TABLE", "CREATE_VIEW", "CREATE_VOLUME", "EXECUTE", "EXECUTE_CLEAN_ROOM_TASK", "EXTERNAL_USE_SCHEMA", "MANAGE", "MANAGE_ALLOWLIST", "MODIFY", "MODIFY_CLEAN_ROOM", "READ_FILES", "READ_PRIVATE_FILES", "READ_VOLUME", "REFRESH", "SELECT", "SET_SHARE_PERMISSION", "USAGE", "USE_CATALOG", "USE_CONNECTION", "USE_MARKETPLACE_ASSETS", "USE_PROVIDER", "USE_RECIPIENT", "USE_SCHEMA", "USE_SHARE", "WRITE_FILES", "WRITE_PRIVATE_FILES", "WRITE_VOLUME"}, "resources.clusters.*.aws_attributes.availability": {"ON_DEMAND", "SPOT", "SPOT_WITH_FALLBACK"}, "resources.clusters.*.aws_attributes.ebs_volume_type": {"GENERAL_PURPOSE_SSD", "THROUGHPUT_OPTIMIZED_HDD"}, @@ -48,7 +48,7 @@ var EnumFields = map[string][]string{ "resources.database_instances.*.state": {"AVAILABLE", "DELETING", "FAILING_OVER", "STARTING", "STOPPED", "UPDATING"}, "resources.external_locations.*.encryption_details.sse_encryption_details.algorithm": {"AWS_SSE_KMS", "AWS_SSE_S3"}, - "resources.external_locations.*.grants[*].privileges[*]": {"ALL_PRIVILEGES", "CREATE_EXTERNAL_TABLE", "CREATE_EXTERNAL_VOLUME", "CREATE_MANAGED_STORAGE", "CREATE_TABLE", "CREATE_VOLUME", "MANAGE", "READ_FILES", "WRITE_FILES"}, + "resources.external_locations.*.grants[*].privileges[*]": {"ACCESS", "ALL_PRIVILEGES", "APPLY_TAG", "BROWSE", "CREATE", "CREATE_CATALOG", "CREATE_CLEAN_ROOM", "CREATE_CONNECTION", "CREATE_EXTERNAL_LOCATION", "CREATE_EXTERNAL_TABLE", "CREATE_EXTERNAL_VOLUME", "CREATE_FOREIGN_CATALOG", "CREATE_FOREIGN_SECURABLE", "CREATE_FUNCTION", "CREATE_MANAGED_STORAGE", "CREATE_MATERIALIZED_VIEW", "CREATE_MODEL", "CREATE_PROVIDER", "CREATE_RECIPIENT", "CREATE_SCHEMA", "CREATE_SERVICE_CREDENTIAL", "CREATE_SHARE", "CREATE_STORAGE_CREDENTIAL", "CREATE_TABLE", "CREATE_VIEW", "CREATE_VOLUME", "EXECUTE", "EXECUTE_CLEAN_ROOM_TASK", "EXTERNAL_USE_SCHEMA", "MANAGE", "MANAGE_ALLOWLIST", "MODIFY", "MODIFY_CLEAN_ROOM", "READ_FILES", "READ_PRIVATE_FILES", "READ_VOLUME", "REFRESH", "SELECT", "SET_SHARE_PERMISSION", "USAGE", "USE_CATALOG", "USE_CONNECTION", "USE_MARKETPLACE_ASSETS", "USE_PROVIDER", "USE_RECIPIENT", "USE_SCHEMA", "USE_SHARE", "WRITE_FILES", "WRITE_PRIVATE_FILES", "WRITE_VOLUME"}, "resources.jobs.*.continuous.pause_status": {"PAUSED", "UNPAUSED"}, "resources.jobs.*.continuous.task_retry_mode": {"NEVER", "ON_FAILURE"}, @@ -144,7 +144,9 @@ var EnumFields = map[string][]string{ "resources.quality_monitors.*.inference_log.problem_type": {"PROBLEM_TYPE_CLASSIFICATION", "PROBLEM_TYPE_REGRESSION"}, "resources.quality_monitors.*.schedule.pause_status": {"PAUSED", "UNPAUSED", "UNSPECIFIED"}, - "resources.schemas.*.grants[*].privileges[*]": {"ALL_PRIVILEGES", "APPLY_TAG", "CREATE_FUNCTION", "CREATE_MATERIALIZED_VIEW", "CREATE_MODEL", "CREATE_TABLE", "CREATE_VOLUME", "EXECUTE", "EXTERNAL_USE_SCHEMA", "MANAGE", "MODIFY", "READ_VOLUME", "REFRESH", "SELECT", "USE_SCHEMA", "WRITE_VOLUME"}, + "resources.registered_models.*.grants[*].privileges[*]": {"ACCESS", "ALL_PRIVILEGES", "APPLY_TAG", "BROWSE", "CREATE", "CREATE_CATALOG", "CREATE_CLEAN_ROOM", "CREATE_CONNECTION", "CREATE_EXTERNAL_LOCATION", "CREATE_EXTERNAL_TABLE", "CREATE_EXTERNAL_VOLUME", "CREATE_FOREIGN_CATALOG", "CREATE_FOREIGN_SECURABLE", "CREATE_FUNCTION", "CREATE_MANAGED_STORAGE", "CREATE_MATERIALIZED_VIEW", "CREATE_MODEL", "CREATE_PROVIDER", "CREATE_RECIPIENT", "CREATE_SCHEMA", "CREATE_SERVICE_CREDENTIAL", "CREATE_SHARE", "CREATE_STORAGE_CREDENTIAL", "CREATE_TABLE", "CREATE_VIEW", "CREATE_VOLUME", "EXECUTE", "EXECUTE_CLEAN_ROOM_TASK", "EXTERNAL_USE_SCHEMA", "MANAGE", "MANAGE_ALLOWLIST", "MODIFY", "MODIFY_CLEAN_ROOM", "READ_FILES", "READ_PRIVATE_FILES", "READ_VOLUME", "REFRESH", "SELECT", "SET_SHARE_PERMISSION", "USAGE", "USE_CATALOG", "USE_CONNECTION", "USE_MARKETPLACE_ASSETS", "USE_PROVIDER", "USE_RECIPIENT", "USE_SCHEMA", "USE_SHARE", "WRITE_FILES", "WRITE_PRIVATE_FILES", "WRITE_VOLUME"}, + + "resources.schemas.*.grants[*].privileges[*]": {"ACCESS", "ALL_PRIVILEGES", "APPLY_TAG", "BROWSE", "CREATE", "CREATE_CATALOG", "CREATE_CLEAN_ROOM", "CREATE_CONNECTION", "CREATE_EXTERNAL_LOCATION", "CREATE_EXTERNAL_TABLE", "CREATE_EXTERNAL_VOLUME", "CREATE_FOREIGN_CATALOG", "CREATE_FOREIGN_SECURABLE", "CREATE_FUNCTION", "CREATE_MANAGED_STORAGE", "CREATE_MATERIALIZED_VIEW", "CREATE_MODEL", "CREATE_PROVIDER", "CREATE_RECIPIENT", "CREATE_SCHEMA", "CREATE_SERVICE_CREDENTIAL", "CREATE_SHARE", "CREATE_STORAGE_CREDENTIAL", "CREATE_TABLE", "CREATE_VIEW", "CREATE_VOLUME", "EXECUTE", "EXECUTE_CLEAN_ROOM_TASK", "EXTERNAL_USE_SCHEMA", "MANAGE", "MANAGE_ALLOWLIST", "MODIFY", "MODIFY_CLEAN_ROOM", "READ_FILES", "READ_PRIVATE_FILES", "READ_VOLUME", "REFRESH", "SELECT", "SET_SHARE_PERMISSION", "USAGE", "USE_CATALOG", "USE_CONNECTION", "USE_MARKETPLACE_ASSETS", "USE_PROVIDER", "USE_RECIPIENT", "USE_SCHEMA", "USE_SHARE", "WRITE_FILES", "WRITE_PRIVATE_FILES", "WRITE_VOLUME"}, "resources.secret_scopes.*.backend_type": {"AZURE_KEYVAULT", "DATABRICKS"}, @@ -159,7 +161,7 @@ var EnumFields = map[string][]string{ "resources.synced_database_tables.*.spec.scheduling_policy": {"CONTINUOUS", "SNAPSHOT", "TRIGGERED"}, "resources.synced_database_tables.*.unity_catalog_provisioning_state": {"ACTIVE", "DEGRADED", "DELETING", "FAILED", "PROVISIONING", "UPDATING"}, - "resources.volumes.*.grants[*].privileges[*]": {"ALL_PRIVILEGES", "APPLY_TAG", "MANAGE", "READ_VOLUME", "WRITE_VOLUME"}, + "resources.volumes.*.grants[*].privileges[*]": {"ACCESS", "ALL_PRIVILEGES", "APPLY_TAG", "BROWSE", "CREATE", "CREATE_CATALOG", "CREATE_CLEAN_ROOM", "CREATE_CONNECTION", "CREATE_EXTERNAL_LOCATION", "CREATE_EXTERNAL_TABLE", "CREATE_EXTERNAL_VOLUME", "CREATE_FOREIGN_CATALOG", "CREATE_FOREIGN_SECURABLE", "CREATE_FUNCTION", "CREATE_MANAGED_STORAGE", "CREATE_MATERIALIZED_VIEW", "CREATE_MODEL", "CREATE_PROVIDER", "CREATE_RECIPIENT", "CREATE_SCHEMA", "CREATE_SERVICE_CREDENTIAL", "CREATE_SHARE", "CREATE_STORAGE_CREDENTIAL", "CREATE_TABLE", "CREATE_VIEW", "CREATE_VOLUME", "EXECUTE", "EXECUTE_CLEAN_ROOM_TASK", "EXTERNAL_USE_SCHEMA", "MANAGE", "MANAGE_ALLOWLIST", "MODIFY", "MODIFY_CLEAN_ROOM", "READ_FILES", "READ_PRIVATE_FILES", "READ_VOLUME", "REFRESH", "SELECT", "SET_SHARE_PERMISSION", "USAGE", "USE_CATALOG", "USE_CONNECTION", "USE_MARKETPLACE_ASSETS", "USE_PROVIDER", "USE_RECIPIENT", "USE_SCHEMA", "USE_SHARE", "WRITE_FILES", "WRITE_PRIVATE_FILES", "WRITE_VOLUME"}, "resources.volumes.*.volume_type": {"EXTERNAL", "MANAGED"}, "variables.*.type": {"complex"}, diff --git a/bundle/internal/validation/generated/required_fields.go b/bundle/internal/validation/generated/required_fields.go index 74679a659c..857caa2523 100644 --- a/bundle/internal/validation/generated/required_fields.go +++ b/bundle/internal/validation/generated/required_fields.go @@ -35,8 +35,7 @@ var RequiredFields = map[string][]string{ "resources.apps.*.resources[*].sql_warehouse": {"id", "permission"}, "resources.apps.*.resources[*].uc_securable": {"permission", "securable_full_name", "securable_type"}, - "resources.catalogs.*": {"name"}, - "resources.catalogs.*.grants[*]": {"privileges", "principal"}, + "resources.catalogs.*": {"name"}, "resources.clusters.*.cluster_log_conf.dbfs": {"destination"}, "resources.clusters.*.cluster_log_conf.s3": {"destination"}, @@ -61,8 +60,7 @@ var RequiredFields = map[string][]string{ "resources.experiments.*": {"name"}, "resources.experiments.*.permissions[*]": {"level"}, - "resources.external_locations.*": {"credential_name", "name", "url"}, - "resources.external_locations.*.grants[*]": {"privileges", "principal"}, + "resources.external_locations.*": {"credential_name", "name", "url"}, "resources.jobs.*.deployment": {"kind"}, "resources.jobs.*.environments[*]": {"environment_key"}, @@ -228,10 +226,7 @@ var RequiredFields = map[string][]string{ "resources.quality_monitors.*.schedule": {"quartz_cron_expression", "timezone_id"}, "resources.quality_monitors.*.time_series": {"granularities", "timestamp_col"}, - "resources.registered_models.*.grants[*]": {"privileges", "principal"}, - - "resources.schemas.*": {"catalog_name", "name"}, - "resources.schemas.*.grants[*]": {"privileges", "principal"}, + "resources.schemas.*": {"catalog_name", "name"}, "resources.secret_scopes.*": {"name"}, "resources.secret_scopes.*.keyvault_metadata": {"dns_name", "resource_id"}, @@ -241,8 +236,7 @@ var RequiredFields = map[string][]string{ "resources.synced_database_tables.*": {"name"}, - "resources.volumes.*": {"catalog_name", "name", "schema_name", "volume_type"}, - "resources.volumes.*.grants[*]": {"privileges", "principal"}, + "resources.volumes.*": {"catalog_name", "name", "schema_name", "volume_type"}, "scripts.*": {"content"}, } diff --git a/bundle/schema/jsonschema.json b/bundle/schema/jsonschema.json index 2f48fb85f9..4c78fa6683 100644 --- a/bundle/schema/jsonschema.json +++ b/bundle/schema/jsonschema.json @@ -339,7 +339,7 @@ "$ref": "#/$defs/string" }, "grants": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.CatalogGrant" + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/catalog.PrivilegeAssignment" }, "lifecycle": { "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.Lifecycle" @@ -374,68 +374,6 @@ } ] }, - "resources.CatalogGrant": { - "oneOf": [ - { - "type": "object", - "properties": { - "principal": { - "$ref": "#/$defs/string" - }, - "privileges": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.CatalogGrantPrivilege" - } - }, - "additionalProperties": false, - "required": [ - "privileges", - "principal" - ] - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, - "resources.CatalogGrantPrivilege": { - "oneOf": [ - { - "type": "string", - "enum": [ - "ALL_PRIVILEGES", - "APPLY_TAG", - "CREATE_CONNECTION", - "CREATE_EXTERNAL_LOCATION", - "CREATE_EXTERNAL_TABLE", - "CREATE_EXTERNAL_VOLUME", - "CREATE_FOREIGN_CATALOG", - "CREATE_FUNCTION", - "CREATE_MANAGED_STORAGE", - "CREATE_MATERIALIZED_VIEW", - "CREATE_MODEL", - "CREATE_SCHEMA", - "CREATE_STORAGE_CREDENTIAL", - "CREATE_TABLE", - "CREATE_VOLUME", - "EXECUTE", - "MANAGE", - "MODIFY", - "READ_VOLUME", - "REFRESH", - "SELECT", - "USE_CATALOG", - "USE_CONNECTION", - "USE_SCHEMA", - "WRITE_VOLUME" - ] - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, "resources.Cluster": { "oneOf": [ { @@ -973,7 +911,7 @@ "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/catalog.FileEventQueue" }, "grants": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.ExternalLocationGrant" + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/catalog.PrivilegeAssignment" }, "lifecycle": { "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.Lifecycle" @@ -1004,79 +942,6 @@ } ] }, - "resources.ExternalLocationGrant": { - "oneOf": [ - { - "type": "object", - "properties": { - "principal": { - "$ref": "#/$defs/string" - }, - "privileges": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.ExternalLocationGrantPrivilege" - } - }, - "additionalProperties": false, - "required": [ - "privileges", - "principal" - ] - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, - "resources.ExternalLocationGrantPrivilege": { - "oneOf": [ - { - "type": "string", - "description": "Privilege to grant on an external location", - "enum": [ - "ALL_PRIVILEGES", - "CREATE_EXTERNAL_TABLE", - "CREATE_EXTERNAL_VOLUME", - "CREATE_MANAGED_STORAGE", - "CREATE_TABLE", - "CREATE_VOLUME", - "MANAGE", - "READ_FILES", - "WRITE_FILES" - ] - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, - "resources.Grant": { - "oneOf": [ - { - "type": "object", - "properties": { - "principal": { - "description": "The name of the principal that will be granted privileges", - "$ref": "#/$defs/string" - }, - "privileges": { - "description": "The privileges to grant to the specified entity", - "$ref": "#/$defs/slice/string" - } - }, - "additionalProperties": false, - "required": [ - "privileges", - "principal" - ] - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, "resources.Job": { "oneOf": [ { @@ -2007,7 +1872,7 @@ "$ref": "#/$defs/string" }, "grants": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.Grant" + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/catalog.PrivilegeAssignment" }, "lifecycle": { "description": "Lifecycle is a struct that contains the lifecycle settings for a resource. It controls the behavior of the resource when it is deployed or destroyed.", @@ -2061,7 +1926,7 @@ "$ref": "#/$defs/string" }, "grants": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.SchemaGrant" + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/catalog.PrivilegeAssignment" }, "lifecycle": { "description": "Lifecycle is a struct that contains the lifecycle settings for a resource. It controls the behavior of the resource when it is deployed or destroyed.", @@ -2092,59 +1957,6 @@ } ] }, - "resources.SchemaGrant": { - "oneOf": [ - { - "type": "object", - "properties": { - "principal": { - "$ref": "#/$defs/string" - }, - "privileges": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.SchemaGrantPrivilege" - } - }, - "additionalProperties": false, - "required": [ - "privileges", - "principal" - ] - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, - "resources.SchemaGrantPrivilege": { - "oneOf": [ - { - "type": "string", - "enum": [ - "ALL_PRIVILEGES", - "APPLY_TAG", - "CREATE_FUNCTION", - "CREATE_MATERIALIZED_VIEW", - "CREATE_MODEL", - "CREATE_TABLE", - "CREATE_VOLUME", - "EXECUTE", - "EXTERNAL_USE_SCHEMA", - "MANAGE", - "MODIFY", - "READ_VOLUME", - "REFRESH", - "SELECT", - "USE_SCHEMA", - "WRITE_VOLUME" - ] - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, "resources.SecretScope": { "oneOf": [ { @@ -2398,7 +2210,7 @@ "$ref": "#/$defs/string" }, "grants": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.VolumeGrant" + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/catalog.PrivilegeAssignment" }, "lifecycle": { "description": "Lifecycle is a struct that contains the lifecycle settings for a resource. It controls the behavior of the resource when it is deployed or destroyed.", @@ -2434,48 +2246,6 @@ } ] }, - "resources.VolumeGrant": { - "oneOf": [ - { - "type": "object", - "properties": { - "principal": { - "$ref": "#/$defs/string" - }, - "privileges": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.VolumeGrantPrivilege" - } - }, - "additionalProperties": false, - "required": [ - "privileges", - "principal" - ] - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, - "resources.VolumeGrantPrivilege": { - "oneOf": [ - { - "type": "string", - "enum": [ - "ALL_PRIVILEGES", - "APPLY_TAG", - "MANAGE", - "READ_VOLUME", - "WRITE_VOLUME" - ] - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, "variable.Lookup": { "oneOf": [ { @@ -4314,6 +4084,91 @@ } ] }, + "catalog.Privilege": { + "oneOf": [ + { + "type": "string", + "enum": [ + "SELECT", + "READ_PRIVATE_FILES", + "WRITE_PRIVATE_FILES", + "CREATE", + "USAGE", + "USE_CATALOG", + "USE_SCHEMA", + "CREATE_SCHEMA", + "CREATE_VIEW", + "CREATE_EXTERNAL_TABLE", + "CREATE_MATERIALIZED_VIEW", + "CREATE_FUNCTION", + "CREATE_MODEL", + "CREATE_CATALOG", + "CREATE_MANAGED_STORAGE", + "CREATE_EXTERNAL_LOCATION", + "CREATE_STORAGE_CREDENTIAL", + "CREATE_SERVICE_CREDENTIAL", + "ACCESS", + "CREATE_SHARE", + "CREATE_RECIPIENT", + "CREATE_PROVIDER", + "USE_SHARE", + "USE_RECIPIENT", + "USE_PROVIDER", + "USE_MARKETPLACE_ASSETS", + "SET_SHARE_PERMISSION", + "MODIFY", + "REFRESH", + "EXECUTE", + "READ_FILES", + "WRITE_FILES", + "CREATE_TABLE", + "ALL_PRIVILEGES", + "CREATE_CONNECTION", + "USE_CONNECTION", + "APPLY_TAG", + "CREATE_FOREIGN_CATALOG", + "CREATE_FOREIGN_SECURABLE", + "MANAGE_ALLOWLIST", + "CREATE_VOLUME", + "CREATE_EXTERNAL_VOLUME", + "READ_VOLUME", + "WRITE_VOLUME", + "MANAGE", + "BROWSE", + "CREATE_CLEAN_ROOM", + "MODIFY_CLEAN_ROOM", + "EXECUTE_CLEAN_ROOM_TASK", + "EXTERNAL_USE_SCHEMA" + ] + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, + "catalog.PrivilegeAssignment": { + "oneOf": [ + { + "type": "object", + "properties": { + "principal": { + "description": "The principal (user email address or group name).\nFor deleted principals, `principal` is empty while `principal_id` is populated.", + "$ref": "#/$defs/string" + }, + "privileges": { + "description": "The privileges assigned to the principal.", + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/catalog.Privilege" + } + }, + "additionalProperties": false + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, "catalog.RegisteredModelAlias": { "oneOf": [ { @@ -11165,34 +11020,6 @@ } ] }, - "resources.CatalogGrant": { - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.CatalogGrant" - } - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, - "resources.CatalogGrantPrivilege": { - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.CatalogGrantPrivilege" - } - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, "resources.ClusterPermission": { "oneOf": [ { @@ -11249,48 +11076,6 @@ } ] }, - "resources.ExternalLocationGrant": { - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.ExternalLocationGrant" - } - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, - "resources.ExternalLocationGrantPrivilege": { - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.ExternalLocationGrantPrivilege" - } - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, - "resources.Grant": { - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.Grant" - } - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, "resources.JobPermission": { "oneOf": [ { @@ -11375,34 +11160,6 @@ } ] }, - "resources.SchemaGrant": { - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.SchemaGrant" - } - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, - "resources.SchemaGrantPrivilege": { - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.SchemaGrantPrivilege" - } - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, "resources.SecretScopePermission": { "oneOf": [ { @@ -11430,34 +11187,6 @@ "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" } ] - }, - "resources.VolumeGrant": { - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.VolumeGrant" - } - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] - }, - "resources.VolumeGrantPrivilege": { - "oneOf": [ - { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.VolumeGrantPrivilege" - } - }, - { - "type": "string", - "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" - } - ] } }, "config.ArtifactFile": { @@ -11520,6 +11249,34 @@ } ] }, + "catalog.Privilege": { + "oneOf": [ + { + "type": "array", + "items": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/catalog.Privilege" + } + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, + "catalog.PrivilegeAssignment": { + "oneOf": [ + { + "type": "array", + "items": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/catalog.PrivilegeAssignment" + } + }, + { + "type": "string", + "pattern": "\\$\\{(var(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\[[0-9]+\\])*)+)\\}" + } + ] + }, "catalog.RegisteredModelAlias": { "oneOf": [ { diff --git a/bundle/schema/jsonschema_for_docs.json b/bundle/schema/jsonschema_for_docs.json index 52b8df408b..8856a74c85 100644 --- a/bundle/schema/jsonschema_for_docs.json +++ b/bundle/schema/jsonschema_for_docs.json @@ -267,7 +267,7 @@ "x-since-version": "v0.287.0" }, "grants": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.CatalogGrant", + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/catalog.PrivilegeAssignment", "x-since-version": "v0.287.0" }, "lifecycle": { @@ -304,54 +304,6 @@ "name" ] }, - "resources.CatalogGrant": { - "type": "object", - "properties": { - "principal": { - "$ref": "#/$defs/string", - "x-since-version": "v0.287.0" - }, - "privileges": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.CatalogGrantPrivilege", - "x-since-version": "v0.287.0" - } - }, - "additionalProperties": false, - "required": [ - "privileges", - "principal" - ] - }, - "resources.CatalogGrantPrivilege": { - "type": "string", - "enum": [ - "ALL_PRIVILEGES", - "APPLY_TAG", - "CREATE_CONNECTION", - "CREATE_EXTERNAL_LOCATION", - "CREATE_EXTERNAL_TABLE", - "CREATE_EXTERNAL_VOLUME", - "CREATE_FOREIGN_CATALOG", - "CREATE_FUNCTION", - "CREATE_MANAGED_STORAGE", - "CREATE_MATERIALIZED_VIEW", - "CREATE_MODEL", - "CREATE_SCHEMA", - "CREATE_STORAGE_CREDENTIAL", - "CREATE_TABLE", - "CREATE_VOLUME", - "EXECUTE", - "MANAGE", - "MODIFY", - "READ_VOLUME", - "REFRESH", - "SELECT", - "USE_CATALOG", - "USE_CONNECTION", - "USE_SCHEMA", - "WRITE_VOLUME" - ] - }, "resources.Cluster": { "type": "object", "description": "Contains a snapshot of the latest user specified settings that were used to create/edit the cluster.", @@ -882,7 +834,7 @@ "x-since-version": "v0.289.0" }, "grants": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.ExternalLocationGrant", + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/catalog.PrivilegeAssignment", "x-since-version": "v0.289.0" }, "lifecycle": { @@ -913,59 +865,6 @@ "url" ] }, - "resources.ExternalLocationGrant": { - "type": "object", - "properties": { - "principal": { - "$ref": "#/$defs/string", - "x-since-version": "v0.289.0" - }, - "privileges": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.ExternalLocationGrantPrivilege", - "x-since-version": "v0.289.0" - } - }, - "additionalProperties": false, - "required": [ - "privileges", - "principal" - ] - }, - "resources.ExternalLocationGrantPrivilege": { - "type": "string", - "description": "Privilege to grant on an external location", - "enum": [ - "ALL_PRIVILEGES", - "CREATE_EXTERNAL_TABLE", - "CREATE_EXTERNAL_VOLUME", - "CREATE_MANAGED_STORAGE", - "CREATE_TABLE", - "CREATE_VOLUME", - "MANAGE", - "READ_FILES", - "WRITE_FILES" - ] - }, - "resources.Grant": { - "type": "object", - "properties": { - "principal": { - "description": "The name of the principal that will be granted privileges", - "$ref": "#/$defs/string", - "x-since-version": "v0.229.0" - }, - "privileges": { - "description": "The privileges to grant to the specified entity", - "$ref": "#/$defs/slice/string", - "x-since-version": "v0.229.0" - } - }, - "additionalProperties": false, - "required": [ - "privileges", - "principal" - ] - }, "resources.Job": { "type": "object", "properties": { @@ -1880,7 +1779,7 @@ "x-since-version": "v0.273.0" }, "grants": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.Grant", + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/catalog.PrivilegeAssignment", "x-since-version": "v0.229.0" }, "lifecycle": { @@ -1937,7 +1836,7 @@ "x-since-version": "v0.229.0" }, "grants": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.SchemaGrant", + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/catalog.PrivilegeAssignment", "x-since-version": "v0.229.0" }, "lifecycle": { @@ -1967,45 +1866,6 @@ ], "markdownDescription": "The schema resource type allows you to define Unity Catalog [schemas](https://docs.databricks.com/api/workspace/schemas/create) for tables and other assets in your workflows and pipelines created as part of a bundle. A schema, different from other resource types, has the following limitations:\n\n- The owner of a schema resource is always the deployment user, and cannot be changed. If `run_as` is specified in the bundle, it will be ignored by operations on the schema.\n- Only fields supported by the corresponding [Schemas object create API](https://docs.databricks.com/api/workspace/schemas/create) are available for the schema resource. For example, `enable_predictive_optimization` is not supported as it is only available on the [update API](https://docs.databricks.com/api/workspace/schemas/update)." }, - "resources.SchemaGrant": { - "type": "object", - "properties": { - "principal": { - "$ref": "#/$defs/string", - "x-since-version": "v0.267.0" - }, - "privileges": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.SchemaGrantPrivilege", - "x-since-version": "v0.267.0" - } - }, - "additionalProperties": false, - "required": [ - "privileges", - "principal" - ] - }, - "resources.SchemaGrantPrivilege": { - "type": "string", - "enum": [ - "ALL_PRIVILEGES", - "APPLY_TAG", - "CREATE_FUNCTION", - "CREATE_MATERIALIZED_VIEW", - "CREATE_MODEL", - "CREATE_TABLE", - "CREATE_VOLUME", - "EXECUTE", - "EXTERNAL_USE_SCHEMA", - "MANAGE", - "MODIFY", - "READ_VOLUME", - "REFRESH", - "SELECT", - "USE_SCHEMA", - "WRITE_VOLUME" - ] - }, "resources.SecretScope": { "type": "object", "properties": { @@ -2236,7 +2096,7 @@ "x-since-version": "v0.236.0" }, "grants": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.VolumeGrant", + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/catalog.PrivilegeAssignment", "x-since-version": "v0.236.0" }, "lifecycle": { @@ -2272,34 +2132,6 @@ ], "markdownDescription": "The volume resource type allows you to define and create Unity Catalog [volumes](https://docs.databricks.com/api/workspace/volumes/create) as part of a bundle. When deploying a bundle with a volume defined, note that:\n\n- A volume cannot be referenced in the `artifact_path` for the bundle until it exists in the workspace. Hence, if you want to use Databricks Asset Bundles to create the volume, you must first define the volume in the bundle, deploy it to create the volume, then reference it in the `artifact_path` in subsequent deployments.\n\n- Volumes in the bundle are not prepended with the `dev_${workspace.current_user.short_name}` prefix when the deployment target has `mode: development` configured. However, you can manually configure this prefix. See [custom-presets](https://docs.databricks.com/dev-tools/bundles/deployment-modes.html#custom-presets)." }, - "resources.VolumeGrant": { - "type": "object", - "properties": { - "principal": { - "$ref": "#/$defs/string", - "x-since-version": "v0.264.1" - }, - "privileges": { - "$ref": "#/$defs/slice/github.com/databricks/cli/bundle/config/resources.VolumeGrantPrivilege", - "x-since-version": "v0.264.1" - } - }, - "additionalProperties": false, - "required": [ - "privileges", - "principal" - ] - }, - "resources.VolumeGrantPrivilege": { - "type": "string", - "enum": [ - "ALL_PRIVILEGES", - "APPLY_TAG", - "MANAGE", - "READ_VOLUME", - "WRITE_VOLUME" - ] - }, "variable.Lookup": { "type": "object", "properties": { @@ -3810,6 +3642,75 @@ "timestamp_col" ] }, + "catalog.Privilege": { + "type": "string", + "enum": [ + "SELECT", + "READ_PRIVATE_FILES", + "WRITE_PRIVATE_FILES", + "CREATE", + "USAGE", + "USE_CATALOG", + "USE_SCHEMA", + "CREATE_SCHEMA", + "CREATE_VIEW", + "CREATE_EXTERNAL_TABLE", + "CREATE_MATERIALIZED_VIEW", + "CREATE_FUNCTION", + "CREATE_MODEL", + "CREATE_CATALOG", + "CREATE_MANAGED_STORAGE", + "CREATE_EXTERNAL_LOCATION", + "CREATE_STORAGE_CREDENTIAL", + "CREATE_SERVICE_CREDENTIAL", + "ACCESS", + "CREATE_SHARE", + "CREATE_RECIPIENT", + "CREATE_PROVIDER", + "USE_SHARE", + "USE_RECIPIENT", + "USE_PROVIDER", + "USE_MARKETPLACE_ASSETS", + "SET_SHARE_PERMISSION", + "MODIFY", + "REFRESH", + "EXECUTE", + "READ_FILES", + "WRITE_FILES", + "CREATE_TABLE", + "ALL_PRIVILEGES", + "CREATE_CONNECTION", + "USE_CONNECTION", + "APPLY_TAG", + "CREATE_FOREIGN_CATALOG", + "CREATE_FOREIGN_SECURABLE", + "MANAGE_ALLOWLIST", + "CREATE_VOLUME", + "CREATE_EXTERNAL_VOLUME", + "READ_VOLUME", + "WRITE_VOLUME", + "MANAGE", + "BROWSE", + "CREATE_CLEAN_ROOM", + "MODIFY_CLEAN_ROOM", + "EXECUTE_CLEAN_ROOM_TASK", + "EXTERNAL_USE_SCHEMA" + ] + }, + "catalog.PrivilegeAssignment": { + "type": "object", + "properties": { + "principal": { + "description": "The principal (user email address or group name).\nFor deleted principals, `principal` is empty while `principal_id` is populated.", + "$ref": "#/$defs/string" + }, + "privileges": { + "description": "The privileges assigned to the principal.", + "$ref": "#/$defs/slice/github.com/databricks/databricks-sdk-go/service/catalog.Privilege" + } + }, + "additionalProperties": false + }, "catalog.RegisteredModelAlias": { "type": "object", "properties": { @@ -9121,18 +9022,6 @@ "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.AppPermission" } }, - "resources.CatalogGrant": { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.CatalogGrant" - } - }, - "resources.CatalogGrantPrivilege": { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.CatalogGrantPrivilege" - } - }, "resources.ClusterPermission": { "type": "array", "items": { @@ -9157,24 +9046,6 @@ "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.DatabaseProjectPermission" } }, - "resources.ExternalLocationGrant": { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.ExternalLocationGrant" - } - }, - "resources.ExternalLocationGrantPrivilege": { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.ExternalLocationGrantPrivilege" - } - }, - "resources.Grant": { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.Grant" - } - }, "resources.JobPermission": { "type": "array", "items": { @@ -9211,18 +9082,6 @@ "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.PipelinePermission" } }, - "resources.SchemaGrant": { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.SchemaGrant" - } - }, - "resources.SchemaGrantPrivilege": { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.SchemaGrantPrivilege" - } - }, "resources.SecretScopePermission": { "type": "array", "items": { @@ -9234,18 +9093,6 @@ "items": { "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.SqlWarehousePermission" } - }, - "resources.VolumeGrant": { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.VolumeGrant" - } - }, - "resources.VolumeGrantPrivilege": { - "type": "array", - "items": { - "$ref": "#/$defs/github.com/databricks/cli/bundle/config/resources.VolumeGrantPrivilege" - } } }, "config.ArtifactFile": { @@ -9276,6 +9123,18 @@ "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/catalog.MonitorMetric" } }, + "catalog.Privilege": { + "type": "array", + "items": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/catalog.Privilege" + } + }, + "catalog.PrivilegeAssignment": { + "type": "array", + "items": { + "$ref": "#/$defs/github.com/databricks/databricks-sdk-go/service/catalog.PrivilegeAssignment" + } + }, "catalog.RegisteredModelAlias": { "type": "array", "items": { diff --git a/bundle/tests/registered_model_test.go b/bundle/tests/registered_model_test.go index e9d572a3a3..ce11656efc 100644 --- a/bundle/tests/registered_model_test.go +++ b/bundle/tests/registered_model_test.go @@ -5,6 +5,7 @@ import ( "github.com/databricks/cli/bundle/config" "github.com/databricks/cli/bundle/config/resources" + "github.com/databricks/databricks-sdk-go/service/catalog" "github.com/stretchr/testify/assert" ) @@ -13,7 +14,7 @@ func assertExpectedModel(t *testing.T, p *resources.RegisteredModel) { assert.Equal(t, "default", p.SchemaName) assert.Equal(t, "comment", p.Comment) assert.Equal(t, "account users", p.Grants[0].Principal) - assert.Equal(t, "EXECUTE", p.Grants[0].Privileges[0]) + assert.Equal(t, catalog.Privilege("EXECUTE"), p.Grants[0].Privileges[0]) } func TestRegisteredModelDevelopment(t *testing.T) { diff --git a/python/codegen/codegen/aliases_patch.py b/python/codegen/codegen/aliases_patch.py new file mode 100644 index 0000000000..864f70afb9 --- /dev/null +++ b/python/codegen/codegen/aliases_patch.py @@ -0,0 +1,25 @@ +# Backward compatibility aliases: maps old generated type names to new names, per namespace. +# These are emitted into each namespace's __init__.py as simple assignments. +ALIASES: dict[str, dict[str, str]] = { + "catalogs": { + "CatalogGrant": "PrivilegeAssignment", + "CatalogGrantDict": "PrivilegeAssignmentDict", + "CatalogGrantParam": "PrivilegeAssignmentParam", + "CatalogGrantPrivilege": "Privilege", + "CatalogGrantPrivilegeParam": "PrivilegeParam", + }, + "schemas": { + "SchemaGrant": "PrivilegeAssignment", + "SchemaGrantDict": "PrivilegeAssignmentDict", + "SchemaGrantParam": "PrivilegeAssignmentParam", + "SchemaGrantPrivilege": "Privilege", + "SchemaGrantPrivilegeParam": "PrivilegeParam", + }, + "volumes": { + "VolumeGrant": "PrivilegeAssignment", + "VolumeGrantDict": "PrivilegeAssignmentDict", + "VolumeGrantParam": "PrivilegeAssignmentParam", + "VolumeGrantPrivilege": "Privilege", + "VolumeGrantPrivilegeParam": "PrivilegeParam", + }, +} diff --git a/python/codegen/codegen/main.py b/python/codegen/codegen/main.py index df26810338..d8764775c5 100644 --- a/python/codegen/codegen/main.py +++ b/python/codegen/codegen/main.py @@ -3,6 +3,7 @@ from pathlib import Path from textwrap import dedent +import codegen.aliases_patch as aliases_patch import codegen.generated_dataclass as generated_dataclass import codegen.generated_dataclass_patch as generated_dataclass_patch import codegen.generated_enum as generated_enum @@ -141,6 +142,8 @@ def _write_exports( for _, enum in enums.items(): exports += [enum.class_name, f"{enum.class_name}Param"] + aliases = aliases_patch.ALIASES.get(namespace, {}) + exports.sort() b = CodeBuilder() @@ -148,6 +151,8 @@ def _write_exports( b.append("__all__ = [\n") for export in exports: b.indent().append_repr(export).append(",").newline() + for old_name in sorted(aliases): + b.indent().append_repr(old_name).append(",").newline() b.append("]").newline() b.newline() b.newline() @@ -159,6 +164,11 @@ def _write_exports( if namespace == "jobs": _append_resolve_recursive_imports(b) + if aliases: + b.newline() + for old_name, new_name in sorted(aliases.items()): + b.append(f"{old_name} = {new_name}").newline() + root_package = packages.get_root_package(namespace) package_path = Path(root_package.replace(".", "/")) diff --git a/python/databricks/bundles/catalogs/__init__.py b/python/databricks/bundles/catalogs/__init__.py index b0b79f2dd5..fc92f42e22 100644 --- a/python/databricks/bundles/catalogs/__init__.py +++ b/python/databricks/bundles/catalogs/__init__.py @@ -10,6 +10,11 @@ "Lifecycle", "LifecycleDict", "LifecycleParam", + "Privilege", + "PrivilegeAssignment", + "PrivilegeAssignmentDict", + "PrivilegeAssignmentParam", + "PrivilegeParam", ] @@ -18,17 +23,20 @@ CatalogDict, CatalogParam, ) -from databricks.bundles.catalogs._models.catalog_grant import ( - CatalogGrant, - CatalogGrantDict, - CatalogGrantParam, -) -from databricks.bundles.catalogs._models.catalog_grant_privilege import ( - CatalogGrantPrivilege, - CatalogGrantPrivilegeParam, -) from databricks.bundles.catalogs._models.lifecycle import ( Lifecycle, LifecycleDict, LifecycleParam, ) +from databricks.bundles.catalogs._models.privilege import Privilege, PrivilegeParam +from databricks.bundles.catalogs._models.privilege_assignment import ( + PrivilegeAssignment, + PrivilegeAssignmentDict, + PrivilegeAssignmentParam, +) + +CatalogGrant = PrivilegeAssignment +CatalogGrantDict = PrivilegeAssignmentDict +CatalogGrantParam = PrivilegeAssignmentParam +CatalogGrantPrivilege = Privilege +CatalogGrantPrivilegeParam = PrivilegeParam diff --git a/python/databricks/bundles/catalogs/_models/catalog.py b/python/databricks/bundles/catalogs/_models/catalog.py index 9d59a29265..368e96a3b2 100644 --- a/python/databricks/bundles/catalogs/_models/catalog.py +++ b/python/databricks/bundles/catalogs/_models/catalog.py @@ -1,11 +1,11 @@ from dataclasses import dataclass, field from typing import TYPE_CHECKING, TypedDict -from databricks.bundles.catalogs._models.catalog_grant import ( - CatalogGrant, - CatalogGrantParam, -) from databricks.bundles.catalogs._models.lifecycle import Lifecycle, LifecycleParam +from databricks.bundles.catalogs._models.privilege_assignment import ( + PrivilegeAssignment, + PrivilegeAssignmentParam, +) from databricks.bundles.core._resource import Resource from databricks.bundles.core._transform import _transform from databricks.bundles.core._transform_to_json import _transform_to_json_value @@ -30,7 +30,7 @@ class Catalog(Resource): connection_name: VariableOrOptional[str] = None - grants: VariableOrList[CatalogGrant] = field(default_factory=list) + grants: VariableOrList[PrivilegeAssignment] = field(default_factory=list) lifecycle: VariableOrOptional[Lifecycle] = None @@ -61,7 +61,7 @@ class CatalogDict(TypedDict, total=False): connection_name: VariableOrOptional[str] - grants: VariableOrList[CatalogGrantParam] + grants: VariableOrList[PrivilegeAssignmentParam] lifecycle: VariableOrOptional[LifecycleParam] diff --git a/python/databricks/bundles/catalogs/_models/catalog_grant.py b/python/databricks/bundles/catalogs/_models/catalog_grant.py deleted file mode 100644 index 6c0ddebb5e..0000000000 --- a/python/databricks/bundles/catalogs/_models/catalog_grant.py +++ /dev/null @@ -1,40 +0,0 @@ -from dataclasses import dataclass, field -from typing import TYPE_CHECKING, TypedDict - -from databricks.bundles.catalogs._models.catalog_grant_privilege import ( - CatalogGrantPrivilege, - CatalogGrantPrivilegeParam, -) -from databricks.bundles.core._transform import _transform -from databricks.bundles.core._transform_to_json import _transform_to_json_value -from databricks.bundles.core._variable import VariableOr, VariableOrList - -if TYPE_CHECKING: - from typing_extensions import Self - - -@dataclass(kw_only=True) -class CatalogGrant: - """""" - - principal: VariableOr[str] - - privileges: VariableOrList[CatalogGrantPrivilege] = field(default_factory=list) - - @classmethod - def from_dict(cls, value: "CatalogGrantDict") -> "Self": - return _transform(cls, value) - - def as_dict(self) -> "CatalogGrantDict": - return _transform_to_json_value(self) # type:ignore - - -class CatalogGrantDict(TypedDict, total=False): - """""" - - principal: VariableOr[str] - - privileges: VariableOrList[CatalogGrantPrivilegeParam] - - -CatalogGrantParam = CatalogGrantDict | CatalogGrant diff --git a/python/databricks/bundles/catalogs/_models/catalog_grant_privilege.py b/python/databricks/bundles/catalogs/_models/catalog_grant_privilege.py deleted file mode 100644 index 97c433876f..0000000000 --- a/python/databricks/bundles/catalogs/_models/catalog_grant_privilege.py +++ /dev/null @@ -1,62 +0,0 @@ -from enum import Enum -from typing import Literal - - -class CatalogGrantPrivilege(Enum): - ALL_PRIVILEGES = "ALL_PRIVILEGES" - APPLY_TAG = "APPLY_TAG" - CREATE_CONNECTION = "CREATE_CONNECTION" - CREATE_EXTERNAL_LOCATION = "CREATE_EXTERNAL_LOCATION" - CREATE_EXTERNAL_TABLE = "CREATE_EXTERNAL_TABLE" - CREATE_EXTERNAL_VOLUME = "CREATE_EXTERNAL_VOLUME" - CREATE_FOREIGN_CATALOG = "CREATE_FOREIGN_CATALOG" - CREATE_FUNCTION = "CREATE_FUNCTION" - CREATE_MANAGED_STORAGE = "CREATE_MANAGED_STORAGE" - CREATE_MATERIALIZED_VIEW = "CREATE_MATERIALIZED_VIEW" - CREATE_MODEL = "CREATE_MODEL" - CREATE_SCHEMA = "CREATE_SCHEMA" - CREATE_STORAGE_CREDENTIAL = "CREATE_STORAGE_CREDENTIAL" - CREATE_TABLE = "CREATE_TABLE" - CREATE_VOLUME = "CREATE_VOLUME" - EXECUTE = "EXECUTE" - MANAGE = "MANAGE" - MODIFY = "MODIFY" - READ_VOLUME = "READ_VOLUME" - REFRESH = "REFRESH" - SELECT = "SELECT" - USE_CATALOG = "USE_CATALOG" - USE_CONNECTION = "USE_CONNECTION" - USE_SCHEMA = "USE_SCHEMA" - WRITE_VOLUME = "WRITE_VOLUME" - - -CatalogGrantPrivilegeParam = ( - Literal[ - "ALL_PRIVILEGES", - "APPLY_TAG", - "CREATE_CONNECTION", - "CREATE_EXTERNAL_LOCATION", - "CREATE_EXTERNAL_TABLE", - "CREATE_EXTERNAL_VOLUME", - "CREATE_FOREIGN_CATALOG", - "CREATE_FUNCTION", - "CREATE_MANAGED_STORAGE", - "CREATE_MATERIALIZED_VIEW", - "CREATE_MODEL", - "CREATE_SCHEMA", - "CREATE_STORAGE_CREDENTIAL", - "CREATE_TABLE", - "CREATE_VOLUME", - "EXECUTE", - "MANAGE", - "MODIFY", - "READ_VOLUME", - "REFRESH", - "SELECT", - "USE_CATALOG", - "USE_CONNECTION", - "USE_SCHEMA", - "WRITE_VOLUME", - ] - | CatalogGrantPrivilege -) diff --git a/python/databricks/bundles/catalogs/_models/privilege.py b/python/databricks/bundles/catalogs/_models/privilege.py new file mode 100644 index 0000000000..20f4e1f557 --- /dev/null +++ b/python/databricks/bundles/catalogs/_models/privilege.py @@ -0,0 +1,112 @@ +from enum import Enum +from typing import Literal + + +class Privilege(Enum): + SELECT = "SELECT" + READ_PRIVATE_FILES = "READ_PRIVATE_FILES" + WRITE_PRIVATE_FILES = "WRITE_PRIVATE_FILES" + CREATE = "CREATE" + USAGE = "USAGE" + USE_CATALOG = "USE_CATALOG" + USE_SCHEMA = "USE_SCHEMA" + CREATE_SCHEMA = "CREATE_SCHEMA" + CREATE_VIEW = "CREATE_VIEW" + CREATE_EXTERNAL_TABLE = "CREATE_EXTERNAL_TABLE" + CREATE_MATERIALIZED_VIEW = "CREATE_MATERIALIZED_VIEW" + CREATE_FUNCTION = "CREATE_FUNCTION" + CREATE_MODEL = "CREATE_MODEL" + CREATE_CATALOG = "CREATE_CATALOG" + CREATE_MANAGED_STORAGE = "CREATE_MANAGED_STORAGE" + CREATE_EXTERNAL_LOCATION = "CREATE_EXTERNAL_LOCATION" + CREATE_STORAGE_CREDENTIAL = "CREATE_STORAGE_CREDENTIAL" + CREATE_SERVICE_CREDENTIAL = "CREATE_SERVICE_CREDENTIAL" + ACCESS = "ACCESS" + CREATE_SHARE = "CREATE_SHARE" + CREATE_RECIPIENT = "CREATE_RECIPIENT" + CREATE_PROVIDER = "CREATE_PROVIDER" + USE_SHARE = "USE_SHARE" + USE_RECIPIENT = "USE_RECIPIENT" + USE_PROVIDER = "USE_PROVIDER" + USE_MARKETPLACE_ASSETS = "USE_MARKETPLACE_ASSETS" + SET_SHARE_PERMISSION = "SET_SHARE_PERMISSION" + MODIFY = "MODIFY" + REFRESH = "REFRESH" + EXECUTE = "EXECUTE" + READ_FILES = "READ_FILES" + WRITE_FILES = "WRITE_FILES" + CREATE_TABLE = "CREATE_TABLE" + ALL_PRIVILEGES = "ALL_PRIVILEGES" + CREATE_CONNECTION = "CREATE_CONNECTION" + USE_CONNECTION = "USE_CONNECTION" + APPLY_TAG = "APPLY_TAG" + CREATE_FOREIGN_CATALOG = "CREATE_FOREIGN_CATALOG" + CREATE_FOREIGN_SECURABLE = "CREATE_FOREIGN_SECURABLE" + MANAGE_ALLOWLIST = "MANAGE_ALLOWLIST" + CREATE_VOLUME = "CREATE_VOLUME" + CREATE_EXTERNAL_VOLUME = "CREATE_EXTERNAL_VOLUME" + READ_VOLUME = "READ_VOLUME" + WRITE_VOLUME = "WRITE_VOLUME" + MANAGE = "MANAGE" + BROWSE = "BROWSE" + CREATE_CLEAN_ROOM = "CREATE_CLEAN_ROOM" + MODIFY_CLEAN_ROOM = "MODIFY_CLEAN_ROOM" + EXECUTE_CLEAN_ROOM_TASK = "EXECUTE_CLEAN_ROOM_TASK" + EXTERNAL_USE_SCHEMA = "EXTERNAL_USE_SCHEMA" + + +PrivilegeParam = ( + Literal[ + "SELECT", + "READ_PRIVATE_FILES", + "WRITE_PRIVATE_FILES", + "CREATE", + "USAGE", + "USE_CATALOG", + "USE_SCHEMA", + "CREATE_SCHEMA", + "CREATE_VIEW", + "CREATE_EXTERNAL_TABLE", + "CREATE_MATERIALIZED_VIEW", + "CREATE_FUNCTION", + "CREATE_MODEL", + "CREATE_CATALOG", + "CREATE_MANAGED_STORAGE", + "CREATE_EXTERNAL_LOCATION", + "CREATE_STORAGE_CREDENTIAL", + "CREATE_SERVICE_CREDENTIAL", + "ACCESS", + "CREATE_SHARE", + "CREATE_RECIPIENT", + "CREATE_PROVIDER", + "USE_SHARE", + "USE_RECIPIENT", + "USE_PROVIDER", + "USE_MARKETPLACE_ASSETS", + "SET_SHARE_PERMISSION", + "MODIFY", + "REFRESH", + "EXECUTE", + "READ_FILES", + "WRITE_FILES", + "CREATE_TABLE", + "ALL_PRIVILEGES", + "CREATE_CONNECTION", + "USE_CONNECTION", + "APPLY_TAG", + "CREATE_FOREIGN_CATALOG", + "CREATE_FOREIGN_SECURABLE", + "MANAGE_ALLOWLIST", + "CREATE_VOLUME", + "CREATE_EXTERNAL_VOLUME", + "READ_VOLUME", + "WRITE_VOLUME", + "MANAGE", + "BROWSE", + "CREATE_CLEAN_ROOM", + "MODIFY_CLEAN_ROOM", + "EXECUTE_CLEAN_ROOM_TASK", + "EXTERNAL_USE_SCHEMA", + ] + | Privilege +) diff --git a/python/databricks/bundles/catalogs/_models/privilege_assignment.py b/python/databricks/bundles/catalogs/_models/privilege_assignment.py new file mode 100644 index 0000000000..f3b6755821 --- /dev/null +++ b/python/databricks/bundles/catalogs/_models/privilege_assignment.py @@ -0,0 +1,51 @@ +from dataclasses import dataclass, field +from typing import TYPE_CHECKING, TypedDict + +from databricks.bundles.catalogs._models.privilege import Privilege, PrivilegeParam +from databricks.bundles.core._transform import _transform +from databricks.bundles.core._transform_to_json import _transform_to_json_value +from databricks.bundles.core._variable import VariableOrList, VariableOrOptional + +if TYPE_CHECKING: + from typing_extensions import Self + + +@dataclass(kw_only=True) +class PrivilegeAssignment: + """""" + + principal: VariableOrOptional[str] = None + """ + The principal (user email address or group name). + For deleted principals, `principal` is empty while `principal_id` is populated. + """ + + privileges: VariableOrList[Privilege] = field(default_factory=list) + """ + The privileges assigned to the principal. + """ + + @classmethod + def from_dict(cls, value: "PrivilegeAssignmentDict") -> "Self": + return _transform(cls, value) + + def as_dict(self) -> "PrivilegeAssignmentDict": + return _transform_to_json_value(self) # type:ignore + + +class PrivilegeAssignmentDict(TypedDict, total=False): + """""" + + principal: VariableOrOptional[str] + """ + The principal (user email address or group name). + For deleted principals, `principal` is empty while `principal_id` is populated. + """ + + privileges: VariableOrList[PrivilegeParam] + """ + The privileges assigned to the principal. + """ + + +PrivilegeAssignmentParam = PrivilegeAssignmentDict | PrivilegeAssignment diff --git a/python/databricks/bundles/schemas/__init__.py b/python/databricks/bundles/schemas/__init__.py index d4d0fa33a3..11517faaab 100644 --- a/python/databricks/bundles/schemas/__init__.py +++ b/python/databricks/bundles/schemas/__init__.py @@ -2,6 +2,11 @@ "Lifecycle", "LifecycleDict", "LifecycleParam", + "Privilege", + "PrivilegeAssignment", + "PrivilegeAssignmentDict", + "PrivilegeAssignmentParam", + "PrivilegeParam", "Schema", "SchemaDict", "SchemaGrant", @@ -18,13 +23,16 @@ LifecycleDict, LifecycleParam, ) -from databricks.bundles.schemas._models.schema import Schema, SchemaDict, SchemaParam -from databricks.bundles.schemas._models.schema_grant import ( - SchemaGrant, - SchemaGrantDict, - SchemaGrantParam, -) -from databricks.bundles.schemas._models.schema_grant_privilege import ( - SchemaGrantPrivilege, - SchemaGrantPrivilegeParam, +from databricks.bundles.schemas._models.privilege import Privilege, PrivilegeParam +from databricks.bundles.schemas._models.privilege_assignment import ( + PrivilegeAssignment, + PrivilegeAssignmentDict, + PrivilegeAssignmentParam, ) +from databricks.bundles.schemas._models.schema import Schema, SchemaDict, SchemaParam + +SchemaGrant = PrivilegeAssignment +SchemaGrantDict = PrivilegeAssignmentDict +SchemaGrantParam = PrivilegeAssignmentParam +SchemaGrantPrivilege = Privilege +SchemaGrantPrivilegeParam = PrivilegeParam diff --git a/python/databricks/bundles/schemas/_models/privilege.py b/python/databricks/bundles/schemas/_models/privilege.py new file mode 100644 index 0000000000..20f4e1f557 --- /dev/null +++ b/python/databricks/bundles/schemas/_models/privilege.py @@ -0,0 +1,112 @@ +from enum import Enum +from typing import Literal + + +class Privilege(Enum): + SELECT = "SELECT" + READ_PRIVATE_FILES = "READ_PRIVATE_FILES" + WRITE_PRIVATE_FILES = "WRITE_PRIVATE_FILES" + CREATE = "CREATE" + USAGE = "USAGE" + USE_CATALOG = "USE_CATALOG" + USE_SCHEMA = "USE_SCHEMA" + CREATE_SCHEMA = "CREATE_SCHEMA" + CREATE_VIEW = "CREATE_VIEW" + CREATE_EXTERNAL_TABLE = "CREATE_EXTERNAL_TABLE" + CREATE_MATERIALIZED_VIEW = "CREATE_MATERIALIZED_VIEW" + CREATE_FUNCTION = "CREATE_FUNCTION" + CREATE_MODEL = "CREATE_MODEL" + CREATE_CATALOG = "CREATE_CATALOG" + CREATE_MANAGED_STORAGE = "CREATE_MANAGED_STORAGE" + CREATE_EXTERNAL_LOCATION = "CREATE_EXTERNAL_LOCATION" + CREATE_STORAGE_CREDENTIAL = "CREATE_STORAGE_CREDENTIAL" + CREATE_SERVICE_CREDENTIAL = "CREATE_SERVICE_CREDENTIAL" + ACCESS = "ACCESS" + CREATE_SHARE = "CREATE_SHARE" + CREATE_RECIPIENT = "CREATE_RECIPIENT" + CREATE_PROVIDER = "CREATE_PROVIDER" + USE_SHARE = "USE_SHARE" + USE_RECIPIENT = "USE_RECIPIENT" + USE_PROVIDER = "USE_PROVIDER" + USE_MARKETPLACE_ASSETS = "USE_MARKETPLACE_ASSETS" + SET_SHARE_PERMISSION = "SET_SHARE_PERMISSION" + MODIFY = "MODIFY" + REFRESH = "REFRESH" + EXECUTE = "EXECUTE" + READ_FILES = "READ_FILES" + WRITE_FILES = "WRITE_FILES" + CREATE_TABLE = "CREATE_TABLE" + ALL_PRIVILEGES = "ALL_PRIVILEGES" + CREATE_CONNECTION = "CREATE_CONNECTION" + USE_CONNECTION = "USE_CONNECTION" + APPLY_TAG = "APPLY_TAG" + CREATE_FOREIGN_CATALOG = "CREATE_FOREIGN_CATALOG" + CREATE_FOREIGN_SECURABLE = "CREATE_FOREIGN_SECURABLE" + MANAGE_ALLOWLIST = "MANAGE_ALLOWLIST" + CREATE_VOLUME = "CREATE_VOLUME" + CREATE_EXTERNAL_VOLUME = "CREATE_EXTERNAL_VOLUME" + READ_VOLUME = "READ_VOLUME" + WRITE_VOLUME = "WRITE_VOLUME" + MANAGE = "MANAGE" + BROWSE = "BROWSE" + CREATE_CLEAN_ROOM = "CREATE_CLEAN_ROOM" + MODIFY_CLEAN_ROOM = "MODIFY_CLEAN_ROOM" + EXECUTE_CLEAN_ROOM_TASK = "EXECUTE_CLEAN_ROOM_TASK" + EXTERNAL_USE_SCHEMA = "EXTERNAL_USE_SCHEMA" + + +PrivilegeParam = ( + Literal[ + "SELECT", + "READ_PRIVATE_FILES", + "WRITE_PRIVATE_FILES", + "CREATE", + "USAGE", + "USE_CATALOG", + "USE_SCHEMA", + "CREATE_SCHEMA", + "CREATE_VIEW", + "CREATE_EXTERNAL_TABLE", + "CREATE_MATERIALIZED_VIEW", + "CREATE_FUNCTION", + "CREATE_MODEL", + "CREATE_CATALOG", + "CREATE_MANAGED_STORAGE", + "CREATE_EXTERNAL_LOCATION", + "CREATE_STORAGE_CREDENTIAL", + "CREATE_SERVICE_CREDENTIAL", + "ACCESS", + "CREATE_SHARE", + "CREATE_RECIPIENT", + "CREATE_PROVIDER", + "USE_SHARE", + "USE_RECIPIENT", + "USE_PROVIDER", + "USE_MARKETPLACE_ASSETS", + "SET_SHARE_PERMISSION", + "MODIFY", + "REFRESH", + "EXECUTE", + "READ_FILES", + "WRITE_FILES", + "CREATE_TABLE", + "ALL_PRIVILEGES", + "CREATE_CONNECTION", + "USE_CONNECTION", + "APPLY_TAG", + "CREATE_FOREIGN_CATALOG", + "CREATE_FOREIGN_SECURABLE", + "MANAGE_ALLOWLIST", + "CREATE_VOLUME", + "CREATE_EXTERNAL_VOLUME", + "READ_VOLUME", + "WRITE_VOLUME", + "MANAGE", + "BROWSE", + "CREATE_CLEAN_ROOM", + "MODIFY_CLEAN_ROOM", + "EXECUTE_CLEAN_ROOM_TASK", + "EXTERNAL_USE_SCHEMA", + ] + | Privilege +) diff --git a/python/databricks/bundles/schemas/_models/privilege_assignment.py b/python/databricks/bundles/schemas/_models/privilege_assignment.py new file mode 100644 index 0000000000..c60d5a82ec --- /dev/null +++ b/python/databricks/bundles/schemas/_models/privilege_assignment.py @@ -0,0 +1,51 @@ +from dataclasses import dataclass, field +from typing import TYPE_CHECKING, TypedDict + +from databricks.bundles.core._transform import _transform +from databricks.bundles.core._transform_to_json import _transform_to_json_value +from databricks.bundles.core._variable import VariableOrList, VariableOrOptional +from databricks.bundles.schemas._models.privilege import Privilege, PrivilegeParam + +if TYPE_CHECKING: + from typing_extensions import Self + + +@dataclass(kw_only=True) +class PrivilegeAssignment: + """""" + + principal: VariableOrOptional[str] = None + """ + The principal (user email address or group name). + For deleted principals, `principal` is empty while `principal_id` is populated. + """ + + privileges: VariableOrList[Privilege] = field(default_factory=list) + """ + The privileges assigned to the principal. + """ + + @classmethod + def from_dict(cls, value: "PrivilegeAssignmentDict") -> "Self": + return _transform(cls, value) + + def as_dict(self) -> "PrivilegeAssignmentDict": + return _transform_to_json_value(self) # type:ignore + + +class PrivilegeAssignmentDict(TypedDict, total=False): + """""" + + principal: VariableOrOptional[str] + """ + The principal (user email address or group name). + For deleted principals, `principal` is empty while `principal_id` is populated. + """ + + privileges: VariableOrList[PrivilegeParam] + """ + The privileges assigned to the principal. + """ + + +PrivilegeAssignmentParam = PrivilegeAssignmentDict | PrivilegeAssignment diff --git a/python/databricks/bundles/schemas/_models/schema.py b/python/databricks/bundles/schemas/_models/schema.py index 58975f0474..d12385e395 100644 --- a/python/databricks/bundles/schemas/_models/schema.py +++ b/python/databricks/bundles/schemas/_models/schema.py @@ -11,9 +11,9 @@ VariableOrOptional, ) from databricks.bundles.schemas._models.lifecycle import Lifecycle, LifecycleParam -from databricks.bundles.schemas._models.schema_grant import ( - SchemaGrant, - SchemaGrantParam, +from databricks.bundles.schemas._models.privilege_assignment import ( + PrivilegeAssignment, + PrivilegeAssignmentParam, ) if TYPE_CHECKING: @@ -39,7 +39,7 @@ class Schema(Resource): User-provided free-form text description. """ - grants: VariableOrList[SchemaGrant] = field(default_factory=list) + grants: VariableOrList[PrivilegeAssignment] = field(default_factory=list) lifecycle: VariableOrOptional[Lifecycle] = None """ @@ -79,7 +79,7 @@ class SchemaDict(TypedDict, total=False): User-provided free-form text description. """ - grants: VariableOrList[SchemaGrantParam] + grants: VariableOrList[PrivilegeAssignmentParam] lifecycle: VariableOrOptional[LifecycleParam] """ diff --git a/python/databricks/bundles/schemas/_models/schema_grant.py b/python/databricks/bundles/schemas/_models/schema_grant.py deleted file mode 100644 index 4997db89c6..0000000000 --- a/python/databricks/bundles/schemas/_models/schema_grant.py +++ /dev/null @@ -1,40 +0,0 @@ -from dataclasses import dataclass, field -from typing import TYPE_CHECKING, TypedDict - -from databricks.bundles.core._transform import _transform -from databricks.bundles.core._transform_to_json import _transform_to_json_value -from databricks.bundles.core._variable import VariableOr, VariableOrList -from databricks.bundles.schemas._models.schema_grant_privilege import ( - SchemaGrantPrivilege, - SchemaGrantPrivilegeParam, -) - -if TYPE_CHECKING: - from typing_extensions import Self - - -@dataclass(kw_only=True) -class SchemaGrant: - """""" - - principal: VariableOr[str] - - privileges: VariableOrList[SchemaGrantPrivilege] = field(default_factory=list) - - @classmethod - def from_dict(cls, value: "SchemaGrantDict") -> "Self": - return _transform(cls, value) - - def as_dict(self) -> "SchemaGrantDict": - return _transform_to_json_value(self) # type:ignore - - -class SchemaGrantDict(TypedDict, total=False): - """""" - - principal: VariableOr[str] - - privileges: VariableOrList[SchemaGrantPrivilegeParam] - - -SchemaGrantParam = SchemaGrantDict | SchemaGrant diff --git a/python/databricks/bundles/schemas/_models/schema_grant_privilege.py b/python/databricks/bundles/schemas/_models/schema_grant_privilege.py deleted file mode 100644 index be00afa961..0000000000 --- a/python/databricks/bundles/schemas/_models/schema_grant_privilege.py +++ /dev/null @@ -1,44 +0,0 @@ -from enum import Enum -from typing import Literal - - -class SchemaGrantPrivilege(Enum): - ALL_PRIVILEGES = "ALL_PRIVILEGES" - APPLY_TAG = "APPLY_TAG" - CREATE_FUNCTION = "CREATE_FUNCTION" - CREATE_MATERIALIZED_VIEW = "CREATE_MATERIALIZED_VIEW" - CREATE_MODEL = "CREATE_MODEL" - CREATE_TABLE = "CREATE_TABLE" - CREATE_VOLUME = "CREATE_VOLUME" - EXECUTE = "EXECUTE" - EXTERNAL_USE_SCHEMA = "EXTERNAL_USE_SCHEMA" - MANAGE = "MANAGE" - MODIFY = "MODIFY" - READ_VOLUME = "READ_VOLUME" - REFRESH = "REFRESH" - SELECT = "SELECT" - USE_SCHEMA = "USE_SCHEMA" - WRITE_VOLUME = "WRITE_VOLUME" - - -SchemaGrantPrivilegeParam = ( - Literal[ - "ALL_PRIVILEGES", - "APPLY_TAG", - "CREATE_FUNCTION", - "CREATE_MATERIALIZED_VIEW", - "CREATE_MODEL", - "CREATE_TABLE", - "CREATE_VOLUME", - "EXECUTE", - "EXTERNAL_USE_SCHEMA", - "MANAGE", - "MODIFY", - "READ_VOLUME", - "REFRESH", - "SELECT", - "USE_SCHEMA", - "WRITE_VOLUME", - ] - | SchemaGrantPrivilege -) diff --git a/python/databricks/bundles/volumes/__init__.py b/python/databricks/bundles/volumes/__init__.py index 065713bf6c..57cf0f1e90 100644 --- a/python/databricks/bundles/volumes/__init__.py +++ b/python/databricks/bundles/volumes/__init__.py @@ -2,6 +2,11 @@ "Lifecycle", "LifecycleDict", "LifecycleParam", + "Privilege", + "PrivilegeAssignment", + "PrivilegeAssignmentDict", + "PrivilegeAssignmentParam", + "PrivilegeParam", "Volume", "VolumeDict", "VolumeGrant", @@ -20,14 +25,17 @@ LifecycleDict, LifecycleParam, ) -from databricks.bundles.volumes._models.volume import Volume, VolumeDict, VolumeParam -from databricks.bundles.volumes._models.volume_grant import ( - VolumeGrant, - VolumeGrantDict, - VolumeGrantParam, -) -from databricks.bundles.volumes._models.volume_grant_privilege import ( - VolumeGrantPrivilege, - VolumeGrantPrivilegeParam, +from databricks.bundles.volumes._models.privilege import Privilege, PrivilegeParam +from databricks.bundles.volumes._models.privilege_assignment import ( + PrivilegeAssignment, + PrivilegeAssignmentDict, + PrivilegeAssignmentParam, ) +from databricks.bundles.volumes._models.volume import Volume, VolumeDict, VolumeParam from databricks.bundles.volumes._models.volume_type import VolumeType, VolumeTypeParam + +VolumeGrant = PrivilegeAssignment +VolumeGrantDict = PrivilegeAssignmentDict +VolumeGrantParam = PrivilegeAssignmentParam +VolumeGrantPrivilege = Privilege +VolumeGrantPrivilegeParam = PrivilegeParam diff --git a/python/databricks/bundles/volumes/_models/privilege.py b/python/databricks/bundles/volumes/_models/privilege.py new file mode 100644 index 0000000000..20f4e1f557 --- /dev/null +++ b/python/databricks/bundles/volumes/_models/privilege.py @@ -0,0 +1,112 @@ +from enum import Enum +from typing import Literal + + +class Privilege(Enum): + SELECT = "SELECT" + READ_PRIVATE_FILES = "READ_PRIVATE_FILES" + WRITE_PRIVATE_FILES = "WRITE_PRIVATE_FILES" + CREATE = "CREATE" + USAGE = "USAGE" + USE_CATALOG = "USE_CATALOG" + USE_SCHEMA = "USE_SCHEMA" + CREATE_SCHEMA = "CREATE_SCHEMA" + CREATE_VIEW = "CREATE_VIEW" + CREATE_EXTERNAL_TABLE = "CREATE_EXTERNAL_TABLE" + CREATE_MATERIALIZED_VIEW = "CREATE_MATERIALIZED_VIEW" + CREATE_FUNCTION = "CREATE_FUNCTION" + CREATE_MODEL = "CREATE_MODEL" + CREATE_CATALOG = "CREATE_CATALOG" + CREATE_MANAGED_STORAGE = "CREATE_MANAGED_STORAGE" + CREATE_EXTERNAL_LOCATION = "CREATE_EXTERNAL_LOCATION" + CREATE_STORAGE_CREDENTIAL = "CREATE_STORAGE_CREDENTIAL" + CREATE_SERVICE_CREDENTIAL = "CREATE_SERVICE_CREDENTIAL" + ACCESS = "ACCESS" + CREATE_SHARE = "CREATE_SHARE" + CREATE_RECIPIENT = "CREATE_RECIPIENT" + CREATE_PROVIDER = "CREATE_PROVIDER" + USE_SHARE = "USE_SHARE" + USE_RECIPIENT = "USE_RECIPIENT" + USE_PROVIDER = "USE_PROVIDER" + USE_MARKETPLACE_ASSETS = "USE_MARKETPLACE_ASSETS" + SET_SHARE_PERMISSION = "SET_SHARE_PERMISSION" + MODIFY = "MODIFY" + REFRESH = "REFRESH" + EXECUTE = "EXECUTE" + READ_FILES = "READ_FILES" + WRITE_FILES = "WRITE_FILES" + CREATE_TABLE = "CREATE_TABLE" + ALL_PRIVILEGES = "ALL_PRIVILEGES" + CREATE_CONNECTION = "CREATE_CONNECTION" + USE_CONNECTION = "USE_CONNECTION" + APPLY_TAG = "APPLY_TAG" + CREATE_FOREIGN_CATALOG = "CREATE_FOREIGN_CATALOG" + CREATE_FOREIGN_SECURABLE = "CREATE_FOREIGN_SECURABLE" + MANAGE_ALLOWLIST = "MANAGE_ALLOWLIST" + CREATE_VOLUME = "CREATE_VOLUME" + CREATE_EXTERNAL_VOLUME = "CREATE_EXTERNAL_VOLUME" + READ_VOLUME = "READ_VOLUME" + WRITE_VOLUME = "WRITE_VOLUME" + MANAGE = "MANAGE" + BROWSE = "BROWSE" + CREATE_CLEAN_ROOM = "CREATE_CLEAN_ROOM" + MODIFY_CLEAN_ROOM = "MODIFY_CLEAN_ROOM" + EXECUTE_CLEAN_ROOM_TASK = "EXECUTE_CLEAN_ROOM_TASK" + EXTERNAL_USE_SCHEMA = "EXTERNAL_USE_SCHEMA" + + +PrivilegeParam = ( + Literal[ + "SELECT", + "READ_PRIVATE_FILES", + "WRITE_PRIVATE_FILES", + "CREATE", + "USAGE", + "USE_CATALOG", + "USE_SCHEMA", + "CREATE_SCHEMA", + "CREATE_VIEW", + "CREATE_EXTERNAL_TABLE", + "CREATE_MATERIALIZED_VIEW", + "CREATE_FUNCTION", + "CREATE_MODEL", + "CREATE_CATALOG", + "CREATE_MANAGED_STORAGE", + "CREATE_EXTERNAL_LOCATION", + "CREATE_STORAGE_CREDENTIAL", + "CREATE_SERVICE_CREDENTIAL", + "ACCESS", + "CREATE_SHARE", + "CREATE_RECIPIENT", + "CREATE_PROVIDER", + "USE_SHARE", + "USE_RECIPIENT", + "USE_PROVIDER", + "USE_MARKETPLACE_ASSETS", + "SET_SHARE_PERMISSION", + "MODIFY", + "REFRESH", + "EXECUTE", + "READ_FILES", + "WRITE_FILES", + "CREATE_TABLE", + "ALL_PRIVILEGES", + "CREATE_CONNECTION", + "USE_CONNECTION", + "APPLY_TAG", + "CREATE_FOREIGN_CATALOG", + "CREATE_FOREIGN_SECURABLE", + "MANAGE_ALLOWLIST", + "CREATE_VOLUME", + "CREATE_EXTERNAL_VOLUME", + "READ_VOLUME", + "WRITE_VOLUME", + "MANAGE", + "BROWSE", + "CREATE_CLEAN_ROOM", + "MODIFY_CLEAN_ROOM", + "EXECUTE_CLEAN_ROOM_TASK", + "EXTERNAL_USE_SCHEMA", + ] + | Privilege +) diff --git a/python/databricks/bundles/volumes/_models/privilege_assignment.py b/python/databricks/bundles/volumes/_models/privilege_assignment.py new file mode 100644 index 0000000000..35b695e10d --- /dev/null +++ b/python/databricks/bundles/volumes/_models/privilege_assignment.py @@ -0,0 +1,51 @@ +from dataclasses import dataclass, field +from typing import TYPE_CHECKING, TypedDict + +from databricks.bundles.core._transform import _transform +from databricks.bundles.core._transform_to_json import _transform_to_json_value +from databricks.bundles.core._variable import VariableOrList, VariableOrOptional +from databricks.bundles.volumes._models.privilege import Privilege, PrivilegeParam + +if TYPE_CHECKING: + from typing_extensions import Self + + +@dataclass(kw_only=True) +class PrivilegeAssignment: + """""" + + principal: VariableOrOptional[str] = None + """ + The principal (user email address or group name). + For deleted principals, `principal` is empty while `principal_id` is populated. + """ + + privileges: VariableOrList[Privilege] = field(default_factory=list) + """ + The privileges assigned to the principal. + """ + + @classmethod + def from_dict(cls, value: "PrivilegeAssignmentDict") -> "Self": + return _transform(cls, value) + + def as_dict(self) -> "PrivilegeAssignmentDict": + return _transform_to_json_value(self) # type:ignore + + +class PrivilegeAssignmentDict(TypedDict, total=False): + """""" + + principal: VariableOrOptional[str] + """ + The principal (user email address or group name). + For deleted principals, `principal` is empty while `principal_id` is populated. + """ + + privileges: VariableOrList[PrivilegeParam] + """ + The privileges assigned to the principal. + """ + + +PrivilegeAssignmentParam = PrivilegeAssignmentDict | PrivilegeAssignment diff --git a/python/databricks/bundles/volumes/_models/volume.py b/python/databricks/bundles/volumes/_models/volume.py index 20132cca96..bf77c831d6 100644 --- a/python/databricks/bundles/volumes/_models/volume.py +++ b/python/databricks/bundles/volumes/_models/volume.py @@ -10,9 +10,9 @@ VariableOrOptional, ) from databricks.bundles.volumes._models.lifecycle import Lifecycle, LifecycleParam -from databricks.bundles.volumes._models.volume_grant import ( - VolumeGrant, - VolumeGrantParam, +from databricks.bundles.volumes._models.privilege_assignment import ( + PrivilegeAssignment, + PrivilegeAssignmentParam, ) from databricks.bundles.volumes._models.volume_type import VolumeType, VolumeTypeParam @@ -44,7 +44,7 @@ class Volume(Resource): The comment attached to the volume """ - grants: VariableOrList[VolumeGrant] = field(default_factory=list) + grants: VariableOrList[PrivilegeAssignment] = field(default_factory=list) lifecycle: VariableOrOptional[Lifecycle] = None """ @@ -89,7 +89,7 @@ class VolumeDict(TypedDict, total=False): The comment attached to the volume """ - grants: VariableOrList[VolumeGrantParam] + grants: VariableOrList[PrivilegeAssignmentParam] lifecycle: VariableOrOptional[LifecycleParam] """ diff --git a/python/databricks/bundles/volumes/_models/volume_grant.py b/python/databricks/bundles/volumes/_models/volume_grant.py deleted file mode 100644 index 3bd580371e..0000000000 --- a/python/databricks/bundles/volumes/_models/volume_grant.py +++ /dev/null @@ -1,40 +0,0 @@ -from dataclasses import dataclass, field -from typing import TYPE_CHECKING, TypedDict - -from databricks.bundles.core._transform import _transform -from databricks.bundles.core._transform_to_json import _transform_to_json_value -from databricks.bundles.core._variable import VariableOr, VariableOrList -from databricks.bundles.volumes._models.volume_grant_privilege import ( - VolumeGrantPrivilege, - VolumeGrantPrivilegeParam, -) - -if TYPE_CHECKING: - from typing_extensions import Self - - -@dataclass(kw_only=True) -class VolumeGrant: - """""" - - principal: VariableOr[str] - - privileges: VariableOrList[VolumeGrantPrivilege] = field(default_factory=list) - - @classmethod - def from_dict(cls, value: "VolumeGrantDict") -> "Self": - return _transform(cls, value) - - def as_dict(self) -> "VolumeGrantDict": - return _transform_to_json_value(self) # type:ignore - - -class VolumeGrantDict(TypedDict, total=False): - """""" - - principal: VariableOr[str] - - privileges: VariableOrList[VolumeGrantPrivilegeParam] - - -VolumeGrantParam = VolumeGrantDict | VolumeGrant diff --git a/python/databricks/bundles/volumes/_models/volume_grant_privilege.py b/python/databricks/bundles/volumes/_models/volume_grant_privilege.py deleted file mode 100644 index d758ca6d82..0000000000 --- a/python/databricks/bundles/volumes/_models/volume_grant_privilege.py +++ /dev/null @@ -1,16 +0,0 @@ -from enum import Enum -from typing import Literal - - -class VolumeGrantPrivilege(Enum): - ALL_PRIVILEGES = "ALL_PRIVILEGES" - APPLY_TAG = "APPLY_TAG" - MANAGE = "MANAGE" - READ_VOLUME = "READ_VOLUME" - WRITE_VOLUME = "WRITE_VOLUME" - - -VolumeGrantPrivilegeParam = ( - Literal["ALL_PRIVILEGES", "APPLY_TAG", "MANAGE", "READ_VOLUME", "WRITE_VOLUME"] - | VolumeGrantPrivilege -)