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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
bundle:
name: deploy-registered-models-basic-$UNIQUE_NAME

resources:
registered_models:
my_registered_model:
name: $NAME
comment: $COMMENT
catalog_name: $CATALOG_NAME
schema_name: $SCHEMA_NAME

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

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

>>> export NAME=my-registered-model-[UNIQUE_NAME]

>>> export COMMENT=original comment

>>> export CATALOG_NAME=main

>>> export SCHEMA_NAME=default

=== create catalog and schema to test diff functionality
>>> [CLI] catalogs create mycatalog-[UNIQUE_NAME]
{
"full_name": "mycatalog-[UNIQUE_NAME]"
}

>>> [CLI] schemas create myschema-[UNIQUE_NAME] mycatalog-[UNIQUE_NAME]
{
"full_name": "mycatalog-[UNIQUE_NAME].myschema-[UNIQUE_NAME]"
}

=== create the registered model
>>> [CLI] bundle plan
create registered_models.my_registered_model

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

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

>>> [CLI] registered-models get main.default.my-registered-model-[UNIQUE_NAME]
{
"name": "my-registered-model-[UNIQUE_NAME]",
"comment": "original comment",
"catalog_name": "main",
"schema_name": "default"
}

=== update the comment, this should not recreate
>>> [CLI] bundle plan
update registered_models.my_registered_model

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

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

>>> [CLI] registered-models get main.default.my-registered-model-[UNIQUE_NAME]
{
"name": "my-registered-model-[UNIQUE_NAME]",
"comment": "updated comment",
"catalog_name": "main",
"schema_name": "default"
}

=== update the name, this should recreate
>>> [CLI] bundle plan
recreate registered_models.my_registered_model

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

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

>>> [CLI] registered-models get main.default.my-registered-model-updated-[UNIQUE_NAME]
{
"name": "my-registered-model-updated-[UNIQUE_NAME]",
"comment": "updated comment",
"catalog_name": "main",
"schema_name": "default"
}

=== update the catalog name, this should recreate
>>> [CLI] bundle plan
recreate registered_models.my_registered_model

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

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

>>> [CLI] registered-models get mycatalog-[UNIQUE_NAME].default.my-registered-model-updated-[UNIQUE_NAME]
{
"name": "my-registered-model-updated-[UNIQUE_NAME]",
"comment": "updated comment",
"catalog_name": "mycatalog-[UNIQUE_NAME]",
"schema_name": "default"
}

=== update the schema name, this should recreate
>>> [CLI] bundle plan
recreate registered_models.my_registered_model

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

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

>>> [CLI] registered-models get mycatalog-[UNIQUE_NAME].myschema-[UNIQUE_NAME].my-registered-model-updated-[UNIQUE_NAME]
{
"name": "my-registered-model-updated-[UNIQUE_NAME]",
"comment": "updated comment",
"catalog_name": "mycatalog-[UNIQUE_NAME]",
"schema_name": "myschema-[UNIQUE_NAME]"
}

>>> [CLI] bundle destroy --auto-approve
The following resources will be deleted:
delete registered_model my_registered_model

All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/deploy-registered-models-basic-[UNIQUE_NAME]/default

Deleting files...
Destroy complete!

>>> [CLI] schemas delete mycatalog-[UNIQUE_NAME].myschema-[UNIQUE_NAME] --force
Copy link
Contributor

Choose a reason for hiding this comment

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

As discussed offline, would be great to use acceptance/bundle/resources/<resource_name>/ schema.

bundle/deploy is really focussed on deploy command but we're also interested in plan/json plan/destroy/summary.

another aspect is to use smaller tests which is good for perf and debugging:

See how this test is organized:

 ~/work/cli/acceptance/bundle/resources % tree -d volumes
volumes
├── change-comment
├── change-name
├── change-schema-name
├── remote-change-name
├── remote-delete
└── set-storage-location

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll address this in a followup PR.


>>> [CLI] catalogs delete mycatalog-[UNIQUE_NAME] --force
50 changes: 50 additions & 0 deletions acceptance/bundle/deploy/registered_models/basic/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
trace export NAME="my-registered-model-$UNIQUE_NAME"
trace export COMMENT="original comment"
trace export CATALOG_NAME="main"
trace export SCHEMA_NAME="default"
envsubst < databricks.yml.tmpl > databricks.yml

title "create catalog and schema to test diff functionality"
catalog_name="mycatalog-${UNIQUE_NAME}"
schema_name="myschema-${UNIQUE_NAME}"
trace $CLI catalogs create ${catalog_name} | jq '{full_name}'
trace $CLI schemas create ${schema_name} ${catalog_name} | jq '{full_name}'

cleanup() {
trace $CLI bundle destroy --auto-approve
trace $CLI schemas delete ${catalog_name}.${schema_name} --force
trace $CLI catalogs delete ${catalog_name} --force
}
trap cleanup EXIT

deploy_registered_model() {
trace $CLI bundle plan
Copy link
Contributor

Choose a reason for hiding this comment

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

recording "bundle debug plan" would be nice as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll address this in a followup PR.

trace $CLI bundle deploy
Copy link
Contributor

Choose a reason for hiding this comment

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

recording non-GET requests would be useful to ensure terraform and direct implementations match. If there is too much difference in payload, it can either be cleaned up or we can just record paths without the payload.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll address this in a followup PR.

registered_model_id=$($CLI bundle summary --output json | jq -r '.resources.registered_models.my_registered_model.id')
trace $CLI registered-models get "${registered_model_id}" | jq '{name, comment, catalog_name, schema_name}'
}

title "create the registered model"
deploy_registered_model

export COMMENT="updated comment"
envsubst < databricks.yml.tmpl > databricks.yml

title "update the comment, this should not recreate"
deploy_registered_model

export NAME="my-registered-model-updated-$UNIQUE_NAME"
envsubst < databricks.yml.tmpl > databricks.yml

title "update the name, this should recreate"
deploy_registered_model

title "update the catalog name, this should recreate"
export CATALOG_NAME="${catalog_name}"
envsubst < databricks.yml.tmpl > databricks.yml
deploy_registered_model

title "update the schema name, this should recreate"
export SCHEMA_NAME="${schema_name}"
envsubst < databricks.yml.tmpl > databricks.yml
deploy_registered_model
3 changes: 3 additions & 0 deletions acceptance/bundle/deploy/registered_models/basic/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Cloud = true
Copy link
Contributor

Choose a reason for hiding this comment

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

Appreciate making it both local and integration test, that adds to confidence.

Local = true
RequiresUnityCatalog = true
27 changes: 27 additions & 0 deletions acceptance/bundle/refschema/out.fields.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2571,6 +2571,33 @@ resources.pipelines.*.trigger.cron.quartz_cron_schedule string INPUT STATE
resources.pipelines.*.trigger.cron.timezone_id string INPUT STATE
resources.pipelines.*.trigger.manual *pipelines.ManualTrigger INPUT STATE
resources.pipelines.*.url string INPUT
resources.registered_models.*.aliases []catalog.RegisteredModelAlias REMOTE
resources.registered_models.*.aliases[*] catalog.RegisteredModelAlias REMOTE
resources.registered_models.*.aliases[*].alias_name string REMOTE
resources.registered_models.*.aliases[*].version_num int REMOTE
resources.registered_models.*.browse_only bool REMOTE
resources.registered_models.*.catalog_name string ALL
resources.registered_models.*.comment string ALL
resources.registered_models.*.created_at int64 REMOTE
resources.registered_models.*.created_by string REMOTE
resources.registered_models.*.full_name string REMOTE
resources.registered_models.*.grants []resources.Grant INPUT
resources.registered_models.*.grants[*] resources.Grant 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.*.id string INPUT
resources.registered_models.*.lifecycle resources.Lifecycle INPUT
resources.registered_models.*.lifecycle.prevent_destroy bool INPUT
resources.registered_models.*.metastore_id string REMOTE
resources.registered_models.*.modified_status string INPUT
resources.registered_models.*.name string ALL
resources.registered_models.*.owner string REMOTE
resources.registered_models.*.schema_name string ALL
resources.registered_models.*.storage_location string ALL
resources.registered_models.*.updated_at int64 REMOTE
resources.registered_models.*.updated_by string REMOTE
resources.registered_models.*.url string INPUT
resources.schemas.*.browse_only bool REMOTE
resources.schemas.*.catalog_name string ALL
resources.schemas.*.catalog_type catalog.CatalogType REMOTE
Expand Down
1 change: 1 addition & 0 deletions bundle/direct/dresources/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var SupportedResources = map[string]any{
"database_catalogs": (*ResourceDatabaseCatalog)(nil),
"synced_database_tables": (*ResourceSyncedDatabaseTable)(nil),
"alerts": (*ResourceAlert)(nil),
"registered_models": (*ResourceRegisteredModel)(nil),
}

func InitAll(client *databricks.WorkspaceClient) (map[string]*Adapter, error) {
Expand Down
28 changes: 22 additions & 6 deletions bundle/direct/dresources/all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,17 @@ var testConfig map[string]any = map[string]any{
Name: "main.myschema.my_synced_table",
},
},

"registered_models": &resources.RegisteredModel{
CreateRegisteredModelRequest: catalog.CreateRegisteredModelRequest{
Name: "my_registered_model",
Comment: "Test registered model",
CatalogName: "main",
SchemaName: "default",
StorageLocation: "s3://my-bucket/my-path",
},
},

"experiments": &resources.MlflowExperiment{
CreateExperiment: ml.CreateExperiment{
Name: "my-experiment",
Expand All @@ -73,6 +84,7 @@ var testConfig map[string]any = map[string]any{
ArtifactLocation: "s3://my-bucket/my-experiment",
},
},

"models": &resources.MlflowModel{
CreateModelRequest: ml.CreateModelRequest{
Name: "my_mlflow_model",
Expand Down Expand Up @@ -162,22 +174,26 @@ func testCRUD(t *testing.T, group string, adapter *Adapter, client *databricks.W
require.Equal(t, remote, remoteStateFromWaitCreate)
}

remappedState, err := adapter.RemapState(remote)
require.NoError(t, err)
require.NotNil(t, remappedState)

remoteStateFromUpdate, err := adapter.DoUpdate(ctx, createdID, newState)
require.NoError(t, err, "DoUpdate failed")
if remoteStateFromUpdate != nil {
require.Equal(t, remote, remoteStateFromUpdate)
remappedStateFromUpdate, err := adapter.RemapState(remoteStateFromUpdate)
require.NoError(t, err)
require.Equal(t, remappedState, remappedStateFromUpdate)
}

remoteStateFromWaitUpdate, err := adapter.WaitAfterUpdate(ctx, newState)
require.NoError(t, err)
if remoteStateFromWaitUpdate != nil {
require.Equal(t, remote, remoteStateFromWaitUpdate)
remappedStateFromWaitUpdate, err := adapter.RemapState(remoteStateFromWaitUpdate)
require.NoError(t, err)
require.Equal(t, remappedState, remappedStateFromWaitUpdate)
}

remappedState, err := adapter.RemapState(remote)
require.NoError(t, err)
require.NotNil(t, remappedState)

require.NoError(t, structwalk.Walk(newState, func(path *structpath.PathNode, val any, field *reflect.StructField) {
remoteValue, err := structaccess.Get(remappedState, path)
if err != nil {
Expand Down
Loading
Loading