Skip to content

Commit 85fdf5e

Browse files
Merge branch 'main' into fix/proxy-server
2 parents 7ec2977 + 877d53b commit 85fdf5e

File tree

15 files changed

+604
-9
lines changed

15 files changed

+604
-9
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
bundle:
2+
name: deploy-registered-models-basic-$UNIQUE_NAME
3+
4+
resources:
5+
registered_models:
6+
my_registered_model:
7+
name: $NAME
8+
comment: $COMMENT
9+
catalog_name: $CATALOG_NAME
10+
schema_name: $SCHEMA_NAME

acceptance/bundle/deploy/registered_models/basic/out.test.toml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
2+
>>> export NAME=my-registered-model-[UNIQUE_NAME]
3+
4+
>>> export COMMENT=original comment
5+
6+
>>> export CATALOG_NAME=main
7+
8+
>>> export SCHEMA_NAME=default
9+
10+
=== create catalog and schema to test diff functionality
11+
>>> [CLI] catalogs create mycatalog-[UNIQUE_NAME]
12+
{
13+
"full_name": "mycatalog-[UNIQUE_NAME]"
14+
}
15+
16+
>>> [CLI] schemas create myschema-[UNIQUE_NAME] mycatalog-[UNIQUE_NAME]
17+
{
18+
"full_name": "mycatalog-[UNIQUE_NAME].myschema-[UNIQUE_NAME]"
19+
}
20+
21+
=== create the registered model
22+
>>> [CLI] bundle plan
23+
create registered_models.my_registered_model
24+
25+
Plan: 1 to add, 0 to change, 0 to delete, 0 unchanged
26+
27+
>>> [CLI] bundle deploy
28+
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/deploy-registered-models-basic-[UNIQUE_NAME]/default/files...
29+
Deploying resources...
30+
Updating deployment state...
31+
Deployment complete!
32+
33+
>>> [CLI] registered-models get main.default.my-registered-model-[UNIQUE_NAME]
34+
{
35+
"name": "my-registered-model-[UNIQUE_NAME]",
36+
"comment": "original comment",
37+
"catalog_name": "main",
38+
"schema_name": "default"
39+
}
40+
41+
=== update the comment, this should not recreate
42+
>>> [CLI] bundle plan
43+
update registered_models.my_registered_model
44+
45+
Plan: 0 to add, 1 to change, 0 to delete, 0 unchanged
46+
47+
>>> [CLI] bundle deploy
48+
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/deploy-registered-models-basic-[UNIQUE_NAME]/default/files...
49+
Deploying resources...
50+
Updating deployment state...
51+
Deployment complete!
52+
53+
>>> [CLI] registered-models get main.default.my-registered-model-[UNIQUE_NAME]
54+
{
55+
"name": "my-registered-model-[UNIQUE_NAME]",
56+
"comment": "updated comment",
57+
"catalog_name": "main",
58+
"schema_name": "default"
59+
}
60+
61+
=== update the name, this should recreate
62+
>>> [CLI] bundle plan
63+
recreate registered_models.my_registered_model
64+
65+
Plan: 1 to add, 0 to change, 1 to delete, 0 unchanged
66+
67+
>>> [CLI] bundle deploy
68+
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/deploy-registered-models-basic-[UNIQUE_NAME]/default/files...
69+
Deploying resources...
70+
Updating deployment state...
71+
Deployment complete!
72+
73+
>>> [CLI] registered-models get main.default.my-registered-model-updated-[UNIQUE_NAME]
74+
{
75+
"name": "my-registered-model-updated-[UNIQUE_NAME]",
76+
"comment": "updated comment",
77+
"catalog_name": "main",
78+
"schema_name": "default"
79+
}
80+
81+
=== update the catalog name, this should recreate
82+
>>> [CLI] bundle plan
83+
recreate registered_models.my_registered_model
84+
85+
Plan: 1 to add, 0 to change, 1 to delete, 0 unchanged
86+
87+
>>> [CLI] bundle deploy
88+
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/deploy-registered-models-basic-[UNIQUE_NAME]/default/files...
89+
Deploying resources...
90+
Updating deployment state...
91+
Deployment complete!
92+
93+
>>> [CLI] registered-models get mycatalog-[UNIQUE_NAME].default.my-registered-model-updated-[UNIQUE_NAME]
94+
{
95+
"name": "my-registered-model-updated-[UNIQUE_NAME]",
96+
"comment": "updated comment",
97+
"catalog_name": "mycatalog-[UNIQUE_NAME]",
98+
"schema_name": "default"
99+
}
100+
101+
=== update the schema name, this should recreate
102+
>>> [CLI] bundle plan
103+
recreate registered_models.my_registered_model
104+
105+
Plan: 1 to add, 0 to change, 1 to delete, 0 unchanged
106+
107+
>>> [CLI] bundle deploy
108+
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/deploy-registered-models-basic-[UNIQUE_NAME]/default/files...
109+
Deploying resources...
110+
Updating deployment state...
111+
Deployment complete!
112+
113+
>>> [CLI] registered-models get mycatalog-[UNIQUE_NAME].myschema-[UNIQUE_NAME].my-registered-model-updated-[UNIQUE_NAME]
114+
{
115+
"name": "my-registered-model-updated-[UNIQUE_NAME]",
116+
"comment": "updated comment",
117+
"catalog_name": "mycatalog-[UNIQUE_NAME]",
118+
"schema_name": "myschema-[UNIQUE_NAME]"
119+
}
120+
121+
>>> [CLI] bundle destroy --auto-approve
122+
The following resources will be deleted:
123+
delete registered_model my_registered_model
124+
125+
All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/deploy-registered-models-basic-[UNIQUE_NAME]/default
126+
127+
Deleting files...
128+
Destroy complete!
129+
130+
>>> [CLI] schemas delete mycatalog-[UNIQUE_NAME].myschema-[UNIQUE_NAME] --force
131+
132+
>>> [CLI] catalogs delete mycatalog-[UNIQUE_NAME] --force
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
trace export NAME="my-registered-model-$UNIQUE_NAME"
2+
trace export COMMENT="original comment"
3+
trace export CATALOG_NAME="main"
4+
trace export SCHEMA_NAME="default"
5+
envsubst < databricks.yml.tmpl > databricks.yml
6+
7+
title "create catalog and schema to test diff functionality"
8+
catalog_name="mycatalog-${UNIQUE_NAME}"
9+
schema_name="myschema-${UNIQUE_NAME}"
10+
trace $CLI catalogs create ${catalog_name} | jq '{full_name}'
11+
trace $CLI schemas create ${schema_name} ${catalog_name} | jq '{full_name}'
12+
13+
cleanup() {
14+
trace $CLI bundle destroy --auto-approve
15+
trace $CLI schemas delete ${catalog_name}.${schema_name} --force
16+
trace $CLI catalogs delete ${catalog_name} --force
17+
}
18+
trap cleanup EXIT
19+
20+
deploy_registered_model() {
21+
trace $CLI bundle plan
22+
trace $CLI bundle deploy
23+
registered_model_id=$($CLI bundle summary --output json | jq -r '.resources.registered_models.my_registered_model.id')
24+
trace $CLI registered-models get "${registered_model_id}" | jq '{name, comment, catalog_name, schema_name}'
25+
}
26+
27+
title "create the registered model"
28+
deploy_registered_model
29+
30+
export COMMENT="updated comment"
31+
envsubst < databricks.yml.tmpl > databricks.yml
32+
33+
title "update the comment, this should not recreate"
34+
deploy_registered_model
35+
36+
export NAME="my-registered-model-updated-$UNIQUE_NAME"
37+
envsubst < databricks.yml.tmpl > databricks.yml
38+
39+
title "update the name, this should recreate"
40+
deploy_registered_model
41+
42+
title "update the catalog name, this should recreate"
43+
export CATALOG_NAME="${catalog_name}"
44+
envsubst < databricks.yml.tmpl > databricks.yml
45+
deploy_registered_model
46+
47+
title "update the schema name, this should recreate"
48+
export SCHEMA_NAME="${schema_name}"
49+
envsubst < databricks.yml.tmpl > databricks.yml
50+
deploy_registered_model
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Cloud = true
2+
Local = true
3+
RequiresUnityCatalog = true

acceptance/bundle/refschema/out.fields.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2571,6 +2571,33 @@ resources.pipelines.*.trigger.cron.quartz_cron_schedule string INPUT STATE
25712571
resources.pipelines.*.trigger.cron.timezone_id string INPUT STATE
25722572
resources.pipelines.*.trigger.manual *pipelines.ManualTrigger INPUT STATE
25732573
resources.pipelines.*.url string INPUT
2574+
resources.registered_models.*.aliases []catalog.RegisteredModelAlias REMOTE
2575+
resources.registered_models.*.aliases[*] catalog.RegisteredModelAlias REMOTE
2576+
resources.registered_models.*.aliases[*].alias_name string REMOTE
2577+
resources.registered_models.*.aliases[*].version_num int REMOTE
2578+
resources.registered_models.*.browse_only bool REMOTE
2579+
resources.registered_models.*.catalog_name string ALL
2580+
resources.registered_models.*.comment string ALL
2581+
resources.registered_models.*.created_at int64 REMOTE
2582+
resources.registered_models.*.created_by string REMOTE
2583+
resources.registered_models.*.full_name string REMOTE
2584+
resources.registered_models.*.grants []resources.Grant INPUT
2585+
resources.registered_models.*.grants[*] resources.Grant INPUT
2586+
resources.registered_models.*.grants[*].principal string INPUT
2587+
resources.registered_models.*.grants[*].privileges []string INPUT
2588+
resources.registered_models.*.grants[*].privileges[*] string INPUT
2589+
resources.registered_models.*.id string INPUT
2590+
resources.registered_models.*.lifecycle resources.Lifecycle INPUT
2591+
resources.registered_models.*.lifecycle.prevent_destroy bool INPUT
2592+
resources.registered_models.*.metastore_id string REMOTE
2593+
resources.registered_models.*.modified_status string INPUT
2594+
resources.registered_models.*.name string ALL
2595+
resources.registered_models.*.owner string REMOTE
2596+
resources.registered_models.*.schema_name string ALL
2597+
resources.registered_models.*.storage_location string ALL
2598+
resources.registered_models.*.updated_at int64 REMOTE
2599+
resources.registered_models.*.updated_by string REMOTE
2600+
resources.registered_models.*.url string INPUT
25742601
resources.schemas.*.browse_only bool REMOTE
25752602
resources.schemas.*.catalog_name string ALL
25762603
resources.schemas.*.catalog_type catalog.CatalogType REMOTE

bundle/direct/bundle_plan.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ func (b *DeploymentBundle) CalculatePlanForDeploy(ctx context.Context, client *d
169169
return false
170170
}
171171

172-
remoteAction, remoteChangeMap = interpretOldStateVsRemoteState(adapter, remoteDiff)
172+
remoteAction, remoteChangeMap = interpretOldStateVsRemoteState(ctx, adapter, remoteDiff, remoteState)
173173
}
174174

175175
entry.Action = max(localAction, remoteAction).String()
@@ -237,7 +237,7 @@ func convertChangesToTriggersMap(adapter *dresources.Adapter, diff []structdiff.
237237
return action, m
238238
}
239239

240-
func interpretOldStateVsRemoteState(adapter *dresources.Adapter, diff []structdiff.Change) (deployplan.ActionType, map[string]deployplan.Trigger) {
240+
func interpretOldStateVsRemoteState(ctx context.Context, adapter *dresources.Adapter, diff []structdiff.Change, remoteState any) (deployplan.ActionType, map[string]deployplan.Trigger) {
241241
action := deployplan.ActionTypeSkip
242242
m := make(map[string]deployplan.Trigger)
243243

@@ -252,7 +252,12 @@ func interpretOldStateVsRemoteState(adapter *dresources.Adapter, diff []structdi
252252
}
253253
continue
254254
}
255-
fieldAction := adapter.ClassifyByTriggers(ch)
255+
fieldAction, err := adapter.ClassifyChange(ch, remoteState)
256+
if err != nil {
257+
logdiag.LogError(ctx, fmt.Errorf("internal error: failed to classify changes: %w", err))
258+
continue
259+
}
260+
256261
if fieldAction > action {
257262
action = fieldAction
258263
}

bundle/direct/dresources/adapter.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ type IResourceNoRefresh interface {
7272

7373
// [Optional] WaitAfterUpdate waits for the resource to become ready after update.
7474
WaitAfterUpdate(ctx context.Context, newState any) error
75+
76+
// [Optional] ClassifyChange classifies a set of changes using custom logic.
77+
ClassifyChange(change structdiff.Change, remoteState any) (deployplan.ActionType, error)
7578
}
7679

7780
// IResourceWithRefresh is an alternative to IResourceNoRefresh but every method can return remoteState.
@@ -111,6 +114,7 @@ type Adapter struct {
111114
doUpdateWithID *calladapt.BoundCaller
112115
waitAfterCreate *calladapt.BoundCaller
113116
waitAfterUpdate *calladapt.BoundCaller
117+
classifyChange *calladapt.BoundCaller
114118

115119
fieldTriggers map[string]deployplan.ActionType
116120
}
@@ -138,6 +142,7 @@ func NewAdapter(typedNil any, client *databricks.WorkspaceClient) (*Adapter, err
138142
doUpdateWithID: nil,
139143
waitAfterCreate: nil,
140144
waitAfterUpdate: nil,
145+
classifyChange: nil,
141146
fieldTriggers: map[string]deployplan.ActionType{},
142147
}
143148

@@ -306,6 +311,10 @@ func (a *Adapter) validate() error {
306311
}
307312
}
308313

314+
if a.classifyChange != nil {
315+
validations = append(validations, "ClassifyChange changes", a.classifyChange.InTypes[1], remoteType)
316+
}
317+
309318
err = validateTypes(validations...)
310319
if err != nil {
311320
return err
@@ -501,6 +510,21 @@ func (a *Adapter) WaitAfterUpdate(ctx context.Context, newState any) (any, error
501510
}
502511
}
503512

513+
func (a *Adapter) ClassifyChange(change structdiff.Change, remoteState any) (deployplan.ActionType, error) {
514+
// If ClassifyChange is not implemented, use FieldTriggers.
515+
if a.classifyChange == nil {
516+
return a.ClassifyByTriggers(change), nil
517+
}
518+
519+
outs, err := a.classifyChange.Call(change, remoteState)
520+
if err != nil {
521+
return deployplan.ActionTypeSkip, err
522+
}
523+
524+
actionType := outs[0].(deployplan.ActionType)
525+
return actionType, nil
526+
}
527+
504528
// prepareCallRequired prepares a call and ensures the method is found.
505529
func prepareCallRequired(resource any, methodName string) (*calladapt.BoundCaller, error) {
506530
caller, err := calladapt.PrepareCall(resource, calladapt.TypeOf[IResource](), methodName)

bundle/direct/dresources/all.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ var SupportedResources = map[string]any{
1919
"database_catalogs": (*ResourceDatabaseCatalog)(nil),
2020
"synced_database_tables": (*ResourceSyncedDatabaseTable)(nil),
2121
"alerts": (*ResourceAlert)(nil),
22+
"registered_models": (*ResourceRegisteredModel)(nil),
2223
}
2324

2425
func InitAll(client *databricks.WorkspaceClient) (map[string]*Adapter, error) {

0 commit comments

Comments
 (0)