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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEXT_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* engine/direct: Added support for Vector Search Endpoints ([#4887](https://github.com/databricks/cli/pull/4887)).
* engine/direct: Exclude deploy-only fields (e.g. `lifecycle`) from the Apps update mask so requests that change both `description` and `lifecycle.started` in the same deploy no longer fail with `INVALID_PARAMETER_VALUE` ([#5042](https://github.com/databricks/cli/pull/5042), [#5051](https://github.com/databricks/cli/pull/5051)).
* engine/direct: Fix phantom diffs from `depends_on` reordering in job tasks ([#4990](https://github.com/databricks/cli/pull/4990)).
* engine/direct: Added support for Databricks App Spaces (`app_spaces` resource type) ([#4982](https://github.com/databricks/cli/pull/4982))

### Dependency updates
* Bump `github.com/databricks/databricks-sdk-go` from v0.126.0 to v0.128.0 ([#4984](https://github.com/databricks/cli/pull/4984), [#5031](https://github.com/databricks/cli/pull/5031)).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
app_spaces:
foo:
name: test-space-$UNIQUE_NAME
description: This is a test app space
5 changes: 5 additions & 0 deletions acceptance/bundle/deployment/bind/app_space/out.test.toml

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

46 changes: 46 additions & 0 deletions acceptance/bundle/deployment/bind/app_space/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

>>> [CLI] apps create-space test-space-[UNIQUE_NAME] --description Pre-existing space
{
"name": "test-space-[UNIQUE_NAME]",
"description": "Pre-existing space"
}

>>> [CLI] bundle deployment bind foo test-space-[UNIQUE_NAME] --auto-approve
Updating deployment state...
Successfully bound app_space with an id 'test-space-[UNIQUE_NAME]'
Run 'bundle deploy' to deploy changes to your workspace

=== Deploy bundle
>>> [CLI] bundle deploy --force-lock --auto-approve
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files...
Deploying resources...
Updating deployment state...
Deployment complete!

>>> [CLI] apps get-space test-space-[UNIQUE_NAME]
{
"name": "test-space-[UNIQUE_NAME]",
"description": "This is a test app space"
}

=== Unbind app space
>>> [CLI] bundle deployment unbind foo
Updating deployment state...

=== Destroy bundle
>>> [CLI] bundle destroy --auto-approve
All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default

Deleting files...
Destroy complete!

=== Read the pre-defined app space again (expecting it still exists):
>>> [CLI] apps get-space test-space-[UNIQUE_NAME]
{
"name": "test-space-[UNIQUE_NAME]",
"description": "This is a test app space"
}

=== Test cleanup
>>> [CLI] apps delete-space test-space-[UNIQUE_NAME]
0
26 changes: 26 additions & 0 deletions acceptance/bundle/deployment/bind/app_space/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
cleanup() {
title "Test cleanup"
trace $CLI apps delete-space "test-space-$UNIQUE_NAME"
echo $?
}
trap cleanup EXIT

envsubst < databricks.yml.tmpl > databricks.yml

trace $CLI apps create-space "test-space-$UNIQUE_NAME" --description "Pre-existing space" | jq '{name, description}'

trace $CLI bundle deployment bind foo "test-space-$UNIQUE_NAME" --auto-approve

title "Deploy bundle"
trace $CLI bundle deploy --force-lock --auto-approve

trace $CLI apps get-space "test-space-$UNIQUE_NAME" | jq '{name, description}'

title "Unbind app space"
trace $CLI bundle deployment unbind foo

title "Destroy bundle"
trace $CLI bundle destroy --auto-approve

title "Read the pre-defined app space again (expecting it still exists): "
trace $CLI apps get-space "test-space-$UNIQUE_NAME" | jq '{name, description}'
10 changes: 10 additions & 0 deletions acceptance/bundle/deployment/bind/app_space/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Local = true
Cloud = true

Ignore = [
".databricks",
"databricks.yml",
]

[EnvMatrix]
DATABRICKS_BUNDLE_ENGINE = ["direct"]
7 changes: 7 additions & 0 deletions acceptance/bundle/invariant/configs/app_space.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
app_spaces:
foo:
name: app-space-$UNIQUE_NAME
2 changes: 1 addition & 1 deletion acceptance/bundle/invariant/continue_293/out.test.toml

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

2 changes: 1 addition & 1 deletion acceptance/bundle/invariant/migrate/out.test.toml

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

1 change: 1 addition & 0 deletions acceptance/bundle/invariant/migrate/test.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ EnvMatrixExclude.no_vector_search_endpoint = ["INPUT_CONFIG=vector_search_endpoi
# Error: Catalog resources are only supported with direct deployment mode
EnvMatrixExclude.no_catalog = ["INPUT_CONFIG=catalog.yml.tmpl"]
EnvMatrixExclude.no_external_location = ["INPUT_CONFIG=external_location.yml.tmpl"]
EnvMatrixExclude.no_app_space = ["INPUT_CONFIG=app_space.yml.tmpl"]

# Cross-resource permission references (e.g. ${resources.jobs.job_b.permissions[0].level})
# don't work in terraform mode: the terraform interpolator converts the path to
Expand Down
2 changes: 1 addition & 1 deletion acceptance/bundle/invariant/no_drift/out.test.toml

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

1 change: 1 addition & 0 deletions acceptance/bundle/invariant/test.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ EnvMatrix.DATABRICKS_BUNDLE_ENGINE = [
EnvMatrix.INPUT_CONFIG = [
"alert.yml.tmpl",
"app.yml.tmpl",
"app_space.yml.tmpl",
"catalog.yml.tmpl",
"cluster.yml.tmpl",
"dashboard.yml.tmpl",
Expand Down
69 changes: 69 additions & 0 deletions acceptance/bundle/refschema/out.fields.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,75 @@ resources.alerts.*.permissions[*].group_name string ALL
resources.alerts.*.permissions[*].level iam.PermissionLevel ALL
resources.alerts.*.permissions[*].service_principal_name string ALL
resources.alerts.*.permissions[*].user_name string ALL
resources.app_spaces.*.create_time *time.Time ALL
resources.app_spaces.*.creator string ALL
resources.app_spaces.*.description string ALL
resources.app_spaces.*.effective_usage_policy_id string ALL
resources.app_spaces.*.effective_user_api_scopes []string ALL
resources.app_spaces.*.effective_user_api_scopes[*] string ALL
resources.app_spaces.*.id string ALL
resources.app_spaces.*.lifecycle resources.Lifecycle INPUT
resources.app_spaces.*.lifecycle.prevent_destroy bool INPUT
resources.app_spaces.*.modified_status string INPUT
resources.app_spaces.*.name string ALL
resources.app_spaces.*.resources []apps.AppResource ALL
resources.app_spaces.*.resources[*] apps.AppResource ALL
resources.app_spaces.*.resources[*].app *apps.AppResourceApp ALL
resources.app_spaces.*.resources[*].app.name string ALL
resources.app_spaces.*.resources[*].app.permission apps.AppResourceAppAppPermission ALL
resources.app_spaces.*.resources[*].database *apps.AppResourceDatabase ALL
resources.app_spaces.*.resources[*].database.database_name string ALL
resources.app_spaces.*.resources[*].database.instance_name string ALL
resources.app_spaces.*.resources[*].database.permission apps.AppResourceDatabaseDatabasePermission ALL
resources.app_spaces.*.resources[*].description string ALL
resources.app_spaces.*.resources[*].experiment *apps.AppResourceExperiment ALL
resources.app_spaces.*.resources[*].experiment.experiment_id string ALL
resources.app_spaces.*.resources[*].experiment.permission apps.AppResourceExperimentExperimentPermission ALL
resources.app_spaces.*.resources[*].genie_space *apps.AppResourceGenieSpace ALL
resources.app_spaces.*.resources[*].genie_space.name string ALL
resources.app_spaces.*.resources[*].genie_space.permission apps.AppResourceGenieSpaceGenieSpacePermission ALL
resources.app_spaces.*.resources[*].genie_space.space_id string ALL
resources.app_spaces.*.resources[*].job *apps.AppResourceJob ALL
resources.app_spaces.*.resources[*].job.id string ALL
resources.app_spaces.*.resources[*].job.permission apps.AppResourceJobJobPermission ALL
resources.app_spaces.*.resources[*].name string ALL
resources.app_spaces.*.resources[*].postgres *apps.AppResourcePostgres ALL
resources.app_spaces.*.resources[*].postgres.branch string ALL
resources.app_spaces.*.resources[*].postgres.database string ALL
resources.app_spaces.*.resources[*].postgres.permission apps.AppResourcePostgresPostgresPermission ALL
resources.app_spaces.*.resources[*].secret *apps.AppResourceSecret ALL
resources.app_spaces.*.resources[*].secret.key string ALL
resources.app_spaces.*.resources[*].secret.permission apps.AppResourceSecretSecretPermission ALL
resources.app_spaces.*.resources[*].secret.scope string ALL
resources.app_spaces.*.resources[*].serving_endpoint *apps.AppResourceServingEndpoint ALL
resources.app_spaces.*.resources[*].serving_endpoint.name string ALL
resources.app_spaces.*.resources[*].serving_endpoint.permission apps.AppResourceServingEndpointServingEndpointPermission ALL
resources.app_spaces.*.resources[*].sql_warehouse *apps.AppResourceSqlWarehouse ALL
resources.app_spaces.*.resources[*].sql_warehouse.id string ALL
resources.app_spaces.*.resources[*].sql_warehouse.permission apps.AppResourceSqlWarehouseSqlWarehousePermission ALL
resources.app_spaces.*.resources[*].uc_securable *apps.AppResourceUcSecurable ALL
resources.app_spaces.*.resources[*].uc_securable.permission apps.AppResourceUcSecurableUcSecurablePermission ALL
resources.app_spaces.*.resources[*].uc_securable.securable_full_name string ALL
resources.app_spaces.*.resources[*].uc_securable.securable_kind string ALL
resources.app_spaces.*.resources[*].uc_securable.securable_type apps.AppResourceUcSecurableUcSecurableType ALL
resources.app_spaces.*.service_principal_client_id string ALL
resources.app_spaces.*.service_principal_id int64 ALL
resources.app_spaces.*.service_principal_name string ALL
resources.app_spaces.*.status *apps.SpaceStatus ALL
resources.app_spaces.*.status.message string ALL
resources.app_spaces.*.status.state apps.SpaceStatusSpaceState ALL
resources.app_spaces.*.update_time *time.Time ALL
resources.app_spaces.*.updater string ALL
resources.app_spaces.*.url string INPUT
resources.app_spaces.*.usage_policy_id string ALL
resources.app_spaces.*.user_api_scopes []string ALL
resources.app_spaces.*.user_api_scopes[*] string ALL
resources.app_spaces.*.permissions.object_id string ALL
resources.app_spaces.*.permissions[*] dresources.StatePermission ALL
resources.app_spaces.*.permissions[*].group_name string ALL
resources.app_spaces.*.permissions[*].level iam.PermissionLevel ALL
resources.app_spaces.*.permissions[*].service_principal_name string ALL
resources.app_spaces.*.permissions[*].user_name string ALL
resources.apps.*.active_deployment *apps.AppDeployment ALL
resources.apps.*.active_deployment.command []string ALL
resources.apps.*.active_deployment.command[*] string ALL
Expand Down
17 changes: 17 additions & 0 deletions acceptance/bundle/resources/app_spaces/basic/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
bundle:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please look into adding invariant tests as well - you need one config in acceptance/bundle/invariant/configs.

Does this resource support permissions?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thanks for calling this out!

App Spaces support 3 different permissions levels (CAN_USE, CAN_CREATE, CAN_MANAGE) via /api/2.0/permissions/app-spaces/{space-name}. I added a new AppSpacePermission type to handle this.

Also, added that invariant config.

name: test-bundle

resources:
app_spaces:
mykey:
name: myspacename
description: my_space_description
resources:
- name: my-serving-endpoint
serving_endpoint:
name: my-endpoint
permission: CAN_QUERY
- name: my-warehouse
sql_warehouse:
id: warehouse-id-1
permission: CAN_USE
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"method": "POST",
"path": "/api/2.0/app-spaces",
"body": {
"description": "my_space_description",
"name": "myspacename",
"resources": [
{
"name": "my-serving-endpoint",
"serving_endpoint": {
"name": "my-endpoint",
"permission": "CAN_QUERY"
}
},
{
"name": "my-warehouse",
"sql_warehouse": {
"id": "warehouse-id-1",
"permission": "CAN_USE"
}
}
]
}
}
{
"method": "DELETE",
"path": "/api/2.0/app-spaces/myspacename"
}
5 changes: 5 additions & 0 deletions acceptance/bundle/resources/app_spaces/basic/out.test.toml

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

45 changes: 45 additions & 0 deletions acceptance/bundle/resources/app_spaces/basic/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

>>> [CLI] bundle validate
Name: test-bundle
Target: default
Workspace:
User: [USERNAME]
Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default

Validation OK!

>>> [CLI] bundle plan
create app_spaces.mykey

Plan: 1 to add, 0 to change, 0 to delete, 0 unchanged

>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Deploying resources...
Updating deployment state...
Deployment complete!

>>> print_requests.py //app-spaces

>>> [CLI] bundle summary
Name: test-bundle
Target: default
Workspace:
User: [USERNAME]
Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default
Resources:
App Spaces:
mykey:
Name: myspacename
URL: (not deployed)

>>> [CLI] bundle destroy --auto-approve
The following resources will be deleted:
delete resources.app_spaces.mykey

All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default

Deleting files...
Destroy complete!

>>> print_requests.py //app-spaces
7 changes: 7 additions & 0 deletions acceptance/bundle/resources/app_spaces/basic/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
trace $CLI bundle validate
trace $CLI bundle plan
trace $CLI bundle deploy
trace print_requests.py //app-spaces > out.requests.$DATABRICKS_BUNDLE_ENGINE.json
trace $CLI bundle summary
trace $CLI bundle destroy --auto-approve
trace print_requests.py //app-spaces >> out.requests.$DATABRICKS_BUNDLE_ENGINE.json
5 changes: 5 additions & 0 deletions acceptance/bundle/resources/app_spaces/basic/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Local = true
Cloud = false

[EnvMatrix]
DATABRICKS_BUNDLE_ENGINE = ["direct"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
bundle:
name: test-bundle

resources:
app_spaces:
mykey:
name: original-space-name
description: my_space_description
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"method": "POST",
"path": "/api/2.0/app-spaces",
"body": {
"description": "my_space_description",
"name": "original-space-name"
}
}
{
"method": "DELETE",
"path": "/api/2.0/app-spaces/original-space-name"
}
{
"method": "POST",
"path": "/api/2.0/app-spaces",
"body": {
"description": "my_space_description",
"name": "renamed-space"
}
}
{
"method": "DELETE",
"path": "/api/2.0/app-spaces/renamed-space"
}
5 changes: 5 additions & 0 deletions acceptance/bundle/resources/app_spaces/recreate/out.test.toml

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

Loading