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
10 changes: 10 additions & 0 deletions acceptance/bundle/deployment/bind/model_service/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
bundle:
name: test-bundle

resources:
model_services:
ms1:
parent: schemas/main.myschema
model_service_id: mysvc
comment: bound service

2 changes: 2 additions & 0 deletions acceptance/bundle/deployment/bind/model_service/out.test.toml

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

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

>>> [CLI] bundle deployment bind ms1 main.myschema.mysvc --auto-approve
Successfully bound model_service with an id 'main.myschema.mysvc'
Run 'bundle deploy' to deploy changes to your workspace

>>> [CLI] bundle summary
Name: test-bundle
Target: default
Workspace:
User: [USERNAME]
Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default
Resources:
Model services:
ms1:
Name: mysvc
URL: (not deployed)

>>> [CLI] bundle deployment unbind ms1

>>> [CLI] bundle summary
Name: test-bundle
Target: default
Workspace:
User: [USERNAME]
Path: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default
Resources:
Model services:
ms1:
Name: mysvc
URL: (not deployed)
5 changes: 5 additions & 0 deletions acceptance/bundle/deployment/bind/model_service/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
trace $CLI bundle deployment bind ms1 main.myschema.mysvc --auto-approve
trace $CLI bundle summary

trace $CLI bundle deployment unbind ms1
trace $CLI bundle summary
18 changes: 18 additions & 0 deletions acceptance/bundle/deployment/bind/model_service/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# AI Gateway securables are direct-engine only.
EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["direct"]

Cloud = false

Ignore = [
".databricks",
]

# The bind flow issues a GET to confirm the remote resource exists before binding.
[[Server]]
Pattern = "GET /api/2.1/unity-catalog/model-services/{name}"
Response.Body = '''
{
"name": "model-services/main.myschema.mysvc",
"comment": "bound service"
}
'''
9 changes: 9 additions & 0 deletions acceptance/bundle/invariant/configs/model_service.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
model_services:
foo:
parent: schemas/main.default
model_service_id: test-model-service-$UNIQUE_NAME
comment: test model service
3 changes: 2 additions & 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.

3 changes: 2 additions & 1 deletion acceptance/bundle/invariant/delete_idempotent/out.test.toml

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

3 changes: 2 additions & 1 deletion acceptance/bundle/invariant/destroy_idempotent/out.test.toml

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

2 changes: 2 additions & 0 deletions acceptance/bundle/invariant/migrate/test.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ EnvMatrixExclude.no_genie_space = ["INPUT_CONFIG=genie_space.yml.tmpl"]
EnvMatrixExclude.no_instance_pool = ["INPUT_CONFIG=instance_pool.yml.tmpl"]
# Cluster policies are direct-only; the terraform deploy that seeds the migration fails for them.
EnvMatrixExclude.no_cluster_policy = ["INPUT_CONFIG=cluster_policy.yml.tmpl"]
# AI Gateway securables are direct-only; the terraform deploy that seeds the migration fails for them.
EnvMatrixExclude.no_model_service = ["INPUT_CONFIG=model_service.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
3 changes: 2 additions & 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.

5 changes: 5 additions & 0 deletions acceptance/bundle/invariant/test.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ EnvMatrix.INPUT_CONFIG = [
"volume_external.yml.tmpl",
"volume_path_job_ref.yml.tmpl",
"volume_uppercase_name.yml.tmpl",
"model_service.yml.tmpl",
]

EnvMatrixExclude.no_alert_on_cloud = ["CONFIG_Cloud=true", "INPUT_CONFIG=alert.yml.tmpl"]
Expand Down Expand Up @@ -108,6 +109,10 @@ EnvMatrixExclude.no_external_location_on_cloud = ["CONFIG_Cloud=true", "INPUT_CO
EnvMatrixExclude.no_external_volume_on_cloud = ["CONFIG_Cloud=true", "INPUT_CONFIG=volume_external.yml.tmpl"]
# Telemetry requires a real model, which cloud invariant tests do not provision.
EnvMatrixExclude.no_model_serving_endpoint_telemetry_on_cloud = ["CONFIG_Cloud=true", "INPUT_CONFIG=model_serving_endpoint_telemetry.yml.tmpl"]
# AI Gateway securables (direct-only) need a real routing target / provider config /
# UC connection to create on cloud, which the invariant tests don't provision; the
# local mock server accepts them, so these run locally only.
EnvMatrixExclude.no_model_service_on_cloud = ["CONFIG_Cloud=true", "INPUT_CONFIG=model_service.yml.tmpl"]
# Fake SQL endpoint for local tests

[[Server]]
Expand Down
62 changes: 62 additions & 0 deletions acceptance/bundle/refschema/out.fields.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2043,6 +2043,68 @@ resources.jobs.*.permissions[*].group_name string ALL
resources.jobs.*.permissions[*].level iam.PermissionLevel ALL
resources.jobs.*.permissions[*].service_principal_name string ALL
resources.jobs.*.permissions[*].user_name string ALL
resources.model_services.*.comment string ALL
resources.model_services.*.config *catalog.ModelServiceConfig ALL
resources.model_services.*.config.inference_table *catalog.InferenceTableConfig ALL
resources.model_services.*.config.inference_table.disabled bool ALL
resources.model_services.*.config.inference_table.is_deleted bool ALL
resources.model_services.*.config.inference_table.parent string ALL
resources.model_services.*.config.inference_table.table string ALL
resources.model_services.*.config.inference_table.table_name_prefix string ALL
resources.model_services.*.config.rate_limits []catalog.RateLimit ALL
resources.model_services.*.config.rate_limits[*] catalog.RateLimit ALL
resources.model_services.*.config.rate_limits[*].key catalog.RateLimitRateLimitKey ALL
resources.model_services.*.config.rate_limits[*].principal string ALL
resources.model_services.*.config.rate_limits[*].renewal_period catalog.RateLimitRateLimitRenewalPeriod ALL
resources.model_services.*.config.rate_limits[*].request_tag_key string ALL
resources.model_services.*.config.rate_limits[*].request_tag_value string ALL
resources.model_services.*.config.rate_limits[*].requests int64 ALL
resources.model_services.*.config.rate_limits[*].tokens int64 ALL
resources.model_services.*.config.routing *catalog.ModelServiceConfigRoutingConfig ALL
resources.model_services.*.config.routing.destinations []catalog.ModelServiceConfigDestinationConfig ALL
resources.model_services.*.config.routing.destinations[*] catalog.ModelServiceConfigDestinationConfig ALL
resources.model_services.*.config.routing.destinations[*].destination_type catalog.ModelServiceConfigDestinationConfigDestinationType ALL
resources.model_services.*.config.routing.destinations[*].external_model_config *catalog.ModelServiceConfigExternalModelConfig ALL
resources.model_services.*.config.routing.destinations[*].external_model_config.model_provider_service string ALL
resources.model_services.*.config.routing.destinations[*].external_model_config.target catalog.ModelProviderServiceConfigModelTargetConfig ALL
resources.model_services.*.config.routing.destinations[*].external_model_config.target.model string ALL
resources.model_services.*.config.routing.destinations[*].external_model_config.target.native_api_types []string ALL
resources.model_services.*.config.routing.destinations[*].external_model_config.target.native_api_types[*] string ALL
resources.model_services.*.config.routing.destinations[*].is_deleted bool ALL
resources.model_services.*.config.routing.destinations[*].name string ALL
resources.model_services.*.config.routing.destinations[*].pay_per_token_config *catalog.ModelServiceConfigPayPerTokenConfig ALL
resources.model_services.*.config.routing.destinations[*].pay_per_token_config.model string ALL
resources.model_services.*.config.routing.destinations[*].provisioned_throughput_config *catalog.ModelServiceConfigProvisionedThroughputConfig ALL
resources.model_services.*.config.routing.destinations[*].provisioned_throughput_config.model string ALL
resources.model_services.*.config.routing.destinations[*].provisioned_throughput_config.model_serving_endpoint string ALL
resources.model_services.*.config.routing.destinations[*].traffic_percentage int ALL
resources.model_services.*.config.routing.fallback *catalog.ModelServiceConfigFallbackConfig ALL
resources.model_services.*.config.routing.fallback.destinations []catalog.ModelServiceConfigDestinationConfig ALL
resources.model_services.*.config.routing.fallback.destinations[*] catalog.ModelServiceConfigDestinationConfig ALL
resources.model_services.*.config.routing.fallback.destinations[*].destination_type catalog.ModelServiceConfigDestinationConfigDestinationType ALL
resources.model_services.*.config.routing.fallback.destinations[*].external_model_config *catalog.ModelServiceConfigExternalModelConfig ALL
resources.model_services.*.config.routing.fallback.destinations[*].external_model_config.model_provider_service string ALL
resources.model_services.*.config.routing.fallback.destinations[*].external_model_config.target catalog.ModelProviderServiceConfigModelTargetConfig ALL
resources.model_services.*.config.routing.fallback.destinations[*].external_model_config.target.model string ALL
resources.model_services.*.config.routing.fallback.destinations[*].external_model_config.target.native_api_types []string ALL
resources.model_services.*.config.routing.fallback.destinations[*].external_model_config.target.native_api_types[*] string ALL
resources.model_services.*.config.routing.fallback.destinations[*].is_deleted bool ALL
resources.model_services.*.config.routing.fallback.destinations[*].name string ALL
resources.model_services.*.config.routing.fallback.destinations[*].pay_per_token_config *catalog.ModelServiceConfigPayPerTokenConfig ALL
resources.model_services.*.config.routing.fallback.destinations[*].pay_per_token_config.model string ALL
resources.model_services.*.config.routing.fallback.destinations[*].provisioned_throughput_config *catalog.ModelServiceConfigProvisionedThroughputConfig ALL
resources.model_services.*.config.routing.fallback.destinations[*].provisioned_throughput_config.model string ALL
resources.model_services.*.config.routing.fallback.destinations[*].provisioned_throughput_config.model_serving_endpoint string ALL
resources.model_services.*.config.routing.fallback.destinations[*].traffic_percentage int ALL
resources.model_services.*.config.routing.first_token_timeout *duration.Duration ALL
resources.model_services.*.config.routing.traffic_splitting *catalog.ModelServiceConfigRoutingConfigTrafficSplitting ALL
resources.model_services.*.id string INPUT
resources.model_services.*.lifecycle resources.Lifecycle INPUT
resources.model_services.*.lifecycle.prevent_destroy bool INPUT
resources.model_services.*.model_service_id string ALL
resources.model_services.*.modified_status string INPUT
resources.model_services.*.parent string ALL
resources.model_services.*.url string INPUT
resources.model_serving_endpoints.*.ai_gateway *serving.AiGatewayConfig ALL
resources.model_serving_endpoints.*.ai_gateway.fallback_config *serving.FallbackConfig ALL
resources.model_serving_endpoints.*.ai_gateway.fallback_config.enabled bool ALL
Expand Down
10 changes: 10 additions & 0 deletions acceptance/bundle/resources/model_services/basic/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
bundle:
name: test-bundle

resources:
model_services:
ms1:
parent: schemas/main.myschema
model_service_id: myservice
comment: COMMENT1

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

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

=== Initial summary before deploy
>>> [CLI] bundle summary -o json
{
"comment": "COMMENT1",
"model_service_id": "myservice",
"modified_status": "created",
"parent": "schemas/main.myschema"
}

=== Verify it does not exist yet
>>> musterr [CLI] ai-gateway get-model-service model-services/main.myschema.myservice
Error: Resource catalog.ModelService not found: main.myschema.myservice

>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Created model_services.ms1
Files: 5 uploaded, 0 deleted
Resources: 1 created, 0 changed, 0 deleted, 0 unchanged

>>> print_requests.py //unity
{
"method": "POST",
"path": "/api/2.1/unity-catalog/model-services",
"q": {
"model_service_id": "myservice",
"parent": "schemas/main.myschema"
},
"body": {
"comment": "COMMENT1"
}
}

=== Summary should show the id (url is not wired for these resources)
>>> [CLI] bundle summary -o json
{
"id": "main.myschema.myservice",
"url": null
}

=== Verify deployment
>>> [CLI] ai-gateway get-model-service model-services/main.myschema.myservice
{
"name": "model-services/main.myschema.myservice",
"comment": "COMMENT1"
}

=== Update comment (should update in place, not recreate)
>>> update_file.py databricks.yml COMMENT1 COMMENT2

>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Updated model_services.ms1
Files: 3 uploaded, 0 deleted
Resources: 0 created, 1 changed, 0 deleted, 0 unchanged

>>> print_requests.py //unity
{
"method": "PATCH",
"path": "/api/2.1/unity-catalog/model-services/main.myschema.myservice",
"q": {
"update_mask": "comment,config"
},
"body": {
"comment": "COMMENT2"
}
}

>>> [CLI] ai-gateway get-model-service model-services/main.myschema.myservice
"COMMENT2"

=== Change an immutable field (should plan a recreate)
>>> update_file.py databricks.yml myservice myservice-renamed

>>> [CLI] bundle plan
recreate model_services.ms1

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

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

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

Destroy: 1 deleted

>>> print_requests.py //unity
{
"method": "DELETE",
"path": "/api/2.1/unity-catalog/model-services/main.myschema.myservice"
}
29 changes: 29 additions & 0 deletions acceptance/bundle/resources/model_services/basic/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
title "Initial summary before deploy"
trace $CLI bundle summary -o json | jq .resources.model_services.ms1

title "Verify it does not exist yet"
trace musterr $CLI ai-gateway get-model-service model-services/main.myschema.myservice

trace $CLI bundle deploy
trace print_requests.py //unity

title "Summary should show the id (url is not wired for these resources)"
trace $CLI bundle summary -o json | jq ".resources.model_services.ms1 | {id, url}"

title "Verify deployment"
trace $CLI ai-gateway get-model-service model-services/main.myschema.myservice | jq '{name, comment}'

title "Update comment (should update in place, not recreate)"
trace update_file.py databricks.yml COMMENT1 COMMENT2
trace $CLI bundle deploy
trace print_requests.py //unity
trace $CLI ai-gateway get-model-service model-services/main.myschema.myservice | jq .comment

title "Change an immutable field (should plan a recreate)"
trace update_file.py databricks.yml myservice myservice-renamed
trace $CLI bundle plan

trace $CLI bundle destroy --auto-approve
trace print_requests.py //unity

rm -f out.requests.txt
3 changes: 3 additions & 0 deletions acceptance/bundle/resources/model_services/basic/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Ignore = [
".databricks",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
bundle:
name: test-bundle

resources:
model_services:
ms1:
parent: schemas/main.myschema
model_service_id: myservice
comment: COMMENT1

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle/default/files...
Created model_services.ms1
Files: 4 uploaded, 0 deleted
Resources: 1 created, 0 changed, 0 deleted, 0 unchanged

=== Delete the resource out of band
>>> [CLI] ai-gateway delete-model-service model-services/main.myschema.myservice

=== Plan should detect the resource is gone and re-create it
>>> [CLI] bundle plan
create model_services.ms1

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

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

Destroy: 0 deleted
Loading
Loading