From 6057b4839618d191362186725d0958135c8bb003 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Thu, 18 Jun 2026 15:44:15 +0200 Subject: [PATCH 1/2] acc: run model_serving_endpoints/basic locally Make the model_serving_endpoints/basic acceptance test runnable against the in-process testserver fake. The test only failed locally on output diffs. Two fixes: - Set IsServicePrincipal in test.toml (and flip Local on) so the fake reports the deployer as a service principal, matching the cloud goldens where the auto-added CAN_MANAGE ACL serializes as service_principal_name. - Have the serving-endpoints testserver populate CreationTimestamp / LastUpdatedTimestamp on create (and bump LastUpdatedTimestamp on update) and force-send an empty Description, matching the fields the real backend echoes back. Sibling serving goldens are regenerated to include these fields. Co-authored-by: Isaac --- .../basic/out.first-requests.terraform.json | 8 ++--- .../basic/out.second-requests.terraform.json | 8 ++--- .../basic/out.test.toml | 2 +- .../model_serving_endpoints/basic/test.toml | 7 ++++- .../catalog-name/out.second-plan.direct.json | 8 +++++ .../name-change/out.second-plan.direct.json | 8 +++++ .../out.second-plan.direct.json | 8 +++++ .../recreate/route-optimized/output.txt | 3 ++ .../schema-name/out.second-plan.direct.json | 8 +++++ .../table-prefix/out.second-plan.direct.json | 8 +++++ .../update/ai-gateway/out.plan.direct.json | 8 +++++ .../out.plan.direct.json | 8 +++++ .../update/config/out.plan.direct.json | 8 +++++ .../email-notifications/out.plan.direct.json | 8 +++++ .../update/tags/out.plan.direct.json | 8 +++++ libs/testserver/serving_endpoints.go | 30 +++++++++++-------- 16 files changed, 116 insertions(+), 22 deletions(-) diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.json b/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.json index d66fe66a2e6..1c0964aa6ec 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.json +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.json @@ -10,13 +10,13 @@ "path": "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_1]", "body": { "access_control_list": [ - { - "permission_level": "CAN_MANAGE", - "service_principal_name": "[USERNAME]" - }, { "permission_level": "CAN_VIEW", "user_name": "deco-test-user@databricks.com" + }, + { + "permission_level": "CAN_MANAGE", + "service_principal_name": "[USERNAME]" } ] } diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.json b/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.json index 8a2028f4504..70fa6b8eb71 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.json +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.json @@ -26,13 +26,13 @@ "path": "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_2]", "body": { "access_control_list": [ - { - "permission_level": "CAN_MANAGE", - "service_principal_name": "[USERNAME]" - }, { "permission_level": "CAN_VIEW", "user_name": "deco-test-user@databricks.com" + }, + { + "permission_level": "CAN_MANAGE", + "service_principal_name": "[USERNAME]" } ] } diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.test.toml b/acceptance/bundle/resources/model_serving_endpoints/basic/out.test.toml index 2d812727e32..e849ec85ace 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/out.test.toml +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/out.test.toml @@ -1,4 +1,4 @@ -Local = false +Local = true Cloud = true RequiresUnityCatalog = true EnvMatrix.DATABRICKS_BUNDLE_ENGINE = ["terraform", "direct"] diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/test.toml b/acceptance/bundle/resources/model_serving_endpoints/basic/test.toml index 2aa692e7f24..28dbed8ca57 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/test.toml +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/test.toml @@ -1,7 +1,12 @@ -Local = false +Local = true Cloud = true RecordRequests = true RequiresUnityCatalog = true +# Cloud goldens were recorded under a service principal, so the deployer's +# auto-added CAN_MANAGE ACL serializes as service_principal_name. Make the +# local fake report the deployer as a service principal to match. +IsServicePrincipal = true + [EnvMatrix] DATABRICKS_BUNDLE_ENGINE = ["terraform", "direct"] diff --git a/acceptance/bundle/resources/model_serving_endpoints/recreate/catalog-name/out.second-plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/recreate/catalog-name/out.second-plan.direct.json index 1c9610dd2fa..2af8d4d7416 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/recreate/catalog-name/out.second-plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/recreate/catalog-name/out.second-plan.direct.json @@ -53,8 +53,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ORIGINAL_ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -73,6 +76,11 @@ "new": "other_catalog", "remote": "main" }, + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "skip", "reason": "empty", diff --git a/acceptance/bundle/resources/model_serving_endpoints/recreate/name-change/out.second-plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/recreate/name-change/out.second-plan.direct.json index 4826a8a87bf..71fe34b4591 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/recreate/name-change/out.second-plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/recreate/name-change/out.second-plan.direct.json @@ -43,8 +43,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ORIGINAL_ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -56,6 +59,11 @@ "endpoint_id": "[UUID]" }, "changes": { + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "name": { "action": "recreate", "reason": "id_field", diff --git a/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/out.second-plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/out.second-plan.direct.json index 5379c464648..fdf9dc54d3b 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/out.second-plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/out.second-plan.direct.json @@ -36,8 +36,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ORIGINAL_ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -49,6 +52,11 @@ "endpoint_id": "[UUID]" }, "changes": { + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "recreate", "reason": "immutable", diff --git a/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/output.txt b/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/output.txt index 2f784d9f37d..d9ede211b2b 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/output.txt +++ b/acceptance/bundle/resources/model_serving_endpoints/recreate/route-optimized/output.txt @@ -57,8 +57,11 @@ Deployment complete! } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ORIGINAL_ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": true, diff --git a/acceptance/bundle/resources/model_serving_endpoints/recreate/schema-name/out.second-plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/recreate/schema-name/out.second-plan.direct.json index 996ec9a09cb..367d2028d50 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/recreate/schema-name/out.second-plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/recreate/schema-name/out.second-plan.direct.json @@ -53,8 +53,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ORIGINAL_ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -73,6 +76,11 @@ "new": "other_schema", "remote": "default" }, + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "skip", "reason": "empty", diff --git a/acceptance/bundle/resources/model_serving_endpoints/recreate/table-prefix/out.second-plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/recreate/table-prefix/out.second-plan.direct.json index c57e2ac8bb8..eb0db4dd581 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/recreate/table-prefix/out.second-plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/recreate/table-prefix/out.second-plan.direct.json @@ -53,8 +53,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ORIGINAL_ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -73,6 +76,11 @@ "new": "other_table", "remote": "my_table" }, + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "skip", "reason": "empty", diff --git a/acceptance/bundle/resources/model_serving_endpoints/update/ai-gateway/out.plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/update/ai-gateway/out.plan.direct.json index b9228ef8c78..a2aa883123f 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/update/ai-gateway/out.plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/update/ai-gateway/out.plan.direct.json @@ -53,8 +53,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -72,6 +75,11 @@ "new": "second-inference-catalog", "remote": "first-inference-catalog" }, + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "skip", "reason": "empty", diff --git a/acceptance/bundle/resources/model_serving_endpoints/update/both_gateway_and_tags/out.plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/update/both_gateway_and_tags/out.plan.direct.json index 6dd458695a2..482f463aa99 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/update/both_gateway_and_tags/out.plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/update/both_gateway_and_tags/out.plan.direct.json @@ -59,8 +59,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -84,6 +87,11 @@ "new": "second-inference-catalog", "remote": "first-inference-catalog" }, + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "skip", "reason": "empty", diff --git a/acceptance/bundle/resources/model_serving_endpoints/update/config/out.plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/update/config/out.plan.direct.json index 7b82abf6da8..4a34e191777 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/update/config/out.plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/update/config/out.plan.direct.json @@ -43,8 +43,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -62,6 +65,11 @@ "new": "gpt-5o-mini", "remote": "gpt-4o-mini" }, + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "skip", "reason": "empty", diff --git a/acceptance/bundle/resources/model_serving_endpoints/update/email-notifications/out.plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/update/email-notifications/out.plan.direct.json index 26087d47805..e43b533ebd9 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/update/email-notifications/out.plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/update/email-notifications/out.plan.direct.json @@ -48,13 +48,16 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "email_notifications": { "on_update_success": [ "user1@example.com" ] }, "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -66,6 +69,11 @@ "endpoint_id": "[UUID]" }, "changes": { + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "email_notifications.on_update_success[0]": { "action": "update", "old": "user1@example.com", diff --git a/acceptance/bundle/resources/model_serving_endpoints/update/tags/out.plan.direct.json b/acceptance/bundle/resources/model_serving_endpoints/update/tags/out.plan.direct.json index 75bcde8e90f..f616085b3e4 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/update/tags/out.plan.direct.json +++ b/acceptance/bundle/resources/model_serving_endpoints/update/tags/out.plan.direct.json @@ -49,8 +49,11 @@ } ] }, + "creation_timestamp": [UNIX_TIME_MILLIS][0], "creator": "[USERNAME]", + "description": "", "id": "[UUID]", + "last_updated_timestamp": [UNIX_TIME_MILLIS][0], "name": "[ENDPOINT_ID]", "permission_level": "CAN_MANAGE", "route_optimized": false, @@ -68,6 +71,11 @@ "endpoint_id": "[UUID]" }, "changes": { + "description": { + "action": "skip", + "reason": "empty", + "remote": "" + }, "route_optimized": { "action": "skip", "reason": "empty", diff --git a/libs/testserver/serving_endpoints.go b/libs/testserver/serving_endpoints.go index 8a7ff891b50..7706b376815 100644 --- a/libs/testserver/serving_endpoints.go +++ b/libs/testserver/serving_endpoints.go @@ -110,23 +110,28 @@ func (s *FakeWorkspace) ServingEndpointCreate(req Request) Response { } } + now := nowMilli() endpoint := serving.ServingEndpointDetailed{ - AiGateway: createReq.AiGateway, - BudgetPolicyId: createReq.BudgetPolicyId, - Config: config, - Creator: s.CurrentUser().UserName, - Description: createReq.Description, - EmailNotifications: createReq.EmailNotifications, - Id: nextUUID(), - Name: createReq.Name, - PermissionLevel: serving.ServingEndpointDetailedPermissionLevelCanManage, - RouteOptimized: createReq.RouteOptimized, - Tags: createReq.Tags, + AiGateway: createReq.AiGateway, + BudgetPolicyId: createReq.BudgetPolicyId, + Config: config, + CreationTimestamp: now, + Creator: s.CurrentUser().UserName, + Description: createReq.Description, + EmailNotifications: createReq.EmailNotifications, + Id: nextUUID(), + LastUpdatedTimestamp: now, + Name: createReq.Name, + PermissionLevel: serving.ServingEndpointDetailedPermissionLevelCanManage, + RouteOptimized: createReq.RouteOptimized, + Tags: createReq.Tags, State: &serving.EndpointState{ ConfigUpdate: serving.EndpointStateConfigUpdateNotUpdating, Ready: serving.EndpointStateReadyNotReady, }, - ForceSendFields: append(createReq.ForceSendFields, "PermissionLevel", "RouteOptimized"), + // Force-send Description so an empty value serializes as "", matching the + // real backend which always echoes the field back on GET. + ForceSendFields: append(createReq.ForceSendFields, "PermissionLevel", "RouteOptimized", "Description"), } s.ServingEndpoints[createReq.Name] = endpoint @@ -180,6 +185,7 @@ func (s *FakeWorkspace) ServingEndpointUpdate(req Request, name string) Response } endpoint.Config = config + endpoint.LastUpdatedTimestamp = nowMilli() endpoint.State = &serving.EndpointState{ ConfigUpdate: serving.EndpointStateConfigUpdateNotUpdating, Ready: serving.EndpointStateReadyNotReady, From cc92b8fa92d3f8b265aa3e0453f62d67e92f7883 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Thu, 18 Jun 2026 17:31:57 +0200 Subject: [PATCH 2/2] acc: sort recorded ACLs in model_serving basic for cross-env stability The terraform engine stores access_control as a set whose iteration order depends on the unmasked principal value, so the local fake SP and the real cloud SP produce different ACL orderings in the recorded PUT. Sort the recorded access_control_list via gron.py --sort-arrays (same pattern as permissions/jobs/delete_one) so the terraform request golden matches both local and cloud. Verified passing on aws-prod-ucws for both engines. Co-authored-by: Isaac --- .../basic/out.first-requests.direct.json | 23 ----------- .../basic/out.first-requests.direct.txt | 9 +++++ .../basic/out.first-requests.terraform.json | 23 ----------- .../basic/out.first-requests.terraform.txt | 9 +++++ .../basic/out.second-requests.direct.json | 27 ------------- .../basic/out.second-requests.direct.txt | 11 ++++++ .../basic/out.second-requests.terraform.json | 39 ------------------- .../basic/out.second-requests.terraform.txt | 15 +++++++ .../model_serving_endpoints/basic/output.txt | 4 -- .../model_serving_endpoints/basic/script | 7 +++- 10 files changed, 49 insertions(+), 118 deletions(-) delete mode 100644 acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.direct.json create mode 100644 acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.direct.txt delete mode 100644 acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.json create mode 100644 acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.txt delete mode 100644 acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.direct.json create mode 100644 acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.direct.txt delete mode 100644 acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.json create mode 100644 acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.txt diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.direct.json b/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.direct.json deleted file mode 100644 index 1c0964aa6ec..00000000000 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.direct.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "method": "POST", - "path": "/api/2.0/serving-endpoints", - "body": { - "name": "[ENDPOINT_NAME_1]" - } -} -{ - "method": "PUT", - "path": "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_1]", - "body": { - "access_control_list": [ - { - "permission_level": "CAN_VIEW", - "user_name": "deco-test-user@databricks.com" - }, - { - "permission_level": "CAN_MANAGE", - "service_principal_name": "[USERNAME]" - } - ] - } -} diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.direct.txt b/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.direct.txt new file mode 100644 index 00000000000..ff4ff00fb8e --- /dev/null +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.direct.txt @@ -0,0 +1,9 @@ +json[0].method = "POST"; +json[0].path = "/api/2.0/serving-endpoints"; +json[0].body.name = "[ENDPOINT_NAME_1]"; +json[1].method = "PUT"; +json[1].path = "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_1]"; +json[1].body.access_control_list[0].permission_level = "CAN_MANAGE"; +json[1].body.access_control_list[0].service_principal_name = "[USERNAME]"; +json[1].body.access_control_list[1].permission_level = "CAN_VIEW"; +json[1].body.access_control_list[1].user_name = "deco-test-user@databricks.com"; diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.json b/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.json deleted file mode 100644 index 1c0964aa6ec..00000000000 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "method": "POST", - "path": "/api/2.0/serving-endpoints", - "body": { - "name": "[ENDPOINT_NAME_1]" - } -} -{ - "method": "PUT", - "path": "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_1]", - "body": { - "access_control_list": [ - { - "permission_level": "CAN_VIEW", - "user_name": "deco-test-user@databricks.com" - }, - { - "permission_level": "CAN_MANAGE", - "service_principal_name": "[USERNAME]" - } - ] - } -} diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.txt b/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.txt new file mode 100644 index 00000000000..ff4ff00fb8e --- /dev/null +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/out.first-requests.terraform.txt @@ -0,0 +1,9 @@ +json[0].method = "POST"; +json[0].path = "/api/2.0/serving-endpoints"; +json[0].body.name = "[ENDPOINT_NAME_1]"; +json[1].method = "PUT"; +json[1].path = "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_1]"; +json[1].body.access_control_list[0].permission_level = "CAN_MANAGE"; +json[1].body.access_control_list[0].service_principal_name = "[USERNAME]"; +json[1].body.access_control_list[1].permission_level = "CAN_VIEW"; +json[1].body.access_control_list[1].user_name = "deco-test-user@databricks.com"; diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.direct.json b/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.direct.json deleted file mode 100644 index a392327a811..00000000000 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.direct.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "method": "DELETE", - "path": "/api/2.0/serving-endpoints/[ENDPOINT_NAME_1]" -} -{ - "method": "POST", - "path": "/api/2.0/serving-endpoints", - "body": { - "name": "[ENDPOINT_NAME_2]" - } -} -{ - "method": "PUT", - "path": "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_2]", - "body": { - "access_control_list": [ - { - "permission_level": "CAN_VIEW", - "user_name": "deco-test-user@databricks.com" - }, - { - "permission_level": "CAN_MANAGE", - "service_principal_name": "[USERNAME]" - } - ] - } -} diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.direct.txt b/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.direct.txt new file mode 100644 index 00000000000..8f5318593a8 --- /dev/null +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.direct.txt @@ -0,0 +1,11 @@ +json[0].method = "DELETE"; +json[0].path = "/api/2.0/serving-endpoints/[ENDPOINT_NAME_1]"; +json[1].method = "POST"; +json[1].path = "/api/2.0/serving-endpoints"; +json[1].body.name = "[ENDPOINT_NAME_2]"; +json[2].method = "PUT"; +json[2].path = "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_2]"; +json[2].body.access_control_list[0].permission_level = "CAN_MANAGE"; +json[2].body.access_control_list[0].service_principal_name = "[USERNAME]"; +json[2].body.access_control_list[1].permission_level = "CAN_VIEW"; +json[2].body.access_control_list[1].user_name = "deco-test-user@databricks.com"; diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.json b/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.json deleted file mode 100644 index 70fa6b8eb71..00000000000 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "method": "PUT", - "path": "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_1]", - "body": { - "access_control_list": [ - { - "permission_level": "CAN_MANAGE", - "user_name": "[USERNAME]" - } - ] - } -} -{ - "method": "DELETE", - "path": "/api/2.0/serving-endpoints/[ENDPOINT_NAME_1]" -} -{ - "method": "POST", - "path": "/api/2.0/serving-endpoints", - "body": { - "name": "[ENDPOINT_NAME_2]" - } -} -{ - "method": "PUT", - "path": "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_2]", - "body": { - "access_control_list": [ - { - "permission_level": "CAN_VIEW", - "user_name": "deco-test-user@databricks.com" - }, - { - "permission_level": "CAN_MANAGE", - "service_principal_name": "[USERNAME]" - } - ] - } -} diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.txt b/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.txt new file mode 100644 index 00000000000..aba548c4913 --- /dev/null +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/out.second-requests.terraform.txt @@ -0,0 +1,15 @@ +json[0].method = "PUT"; +json[0].path = "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_1]"; +json[0].body.access_control_list[0].permission_level = "CAN_MANAGE"; +json[0].body.access_control_list[0].user_name = "[USERNAME]"; +json[1].method = "DELETE"; +json[1].path = "/api/2.0/serving-endpoints/[ENDPOINT_NAME_1]"; +json[2].method = "POST"; +json[2].path = "/api/2.0/serving-endpoints"; +json[2].body.name = "[ENDPOINT_NAME_2]"; +json[3].method = "PUT"; +json[3].path = "/api/2.0/permissions/serving-endpoints/[ENDPOINT_ID_2]"; +json[3].body.access_control_list[0].permission_level = "CAN_MANAGE"; +json[3].body.access_control_list[0].service_principal_name = "[USERNAME]"; +json[3].body.access_control_list[1].permission_level = "CAN_VIEW"; +json[3].body.access_control_list[1].user_name = "deco-test-user@databricks.com"; diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/output.txt b/acceptance/bundle/resources/model_serving_endpoints/basic/output.txt index 7b3b010eedd..0455fad681a 100644 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/output.txt +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/output.txt @@ -7,8 +7,6 @@ Deploying resources... Updating deployment state... Deployment complete! ->>> print_requests.py //serving-endpoints - === Print the GET endpoint details { "name": "[ENDPOINT_NAME_1]", @@ -23,8 +21,6 @@ Deploying resources... Updating deployment state... Deployment complete! ->>> print_requests.py //serving-endpoints - === Print the GET endpoint details { "name": "[ENDPOINT_NAME_2]", diff --git a/acceptance/bundle/resources/model_serving_endpoints/basic/script b/acceptance/bundle/resources/model_serving_endpoints/basic/script index c06b058d59f..3ff3f64ab28 100755 --- a/acceptance/bundle/resources/model_serving_endpoints/basic/script +++ b/acceptance/bundle/resources/model_serving_endpoints/basic/script @@ -10,7 +10,10 @@ trap cleanup EXIT trace $CLI bundle plan -o json > out.first-plan.$DATABRICKS_BUNDLE_ENGINE.json trace $CLI bundle deploy -trace print_requests.py //serving-endpoints > out.first-requests.$DATABRICKS_BUNDLE_ENGINE.json +# Sort access_control_list: the terraform engine stores it as a set whose order +# depends on the (unmasked) principal value, so it differs between the local fake +# SP and the real cloud SP. Sorting makes the recorded request stable across both. +print_requests.py //serving-endpoints | gron.py --sort-arrays access_control_list > out.first-requests.$DATABRICKS_BUNDLE_ENGINE.txt echo "$ENDPOINT_NAME:ENDPOINT_NAME_1" >> ACC_REPLS @@ -26,7 +29,7 @@ export ENDPOINT_NAME="test-endpoint-$UNIQUE_NAME-2" envsubst < databricks.yml.tmpl > databricks.yml trace $CLI bundle plan -o json > out.second-plan.$DATABRICKS_BUNDLE_ENGINE.json trace $CLI bundle deploy -trace print_requests.py //serving-endpoints > out.second-requests.$DATABRICKS_BUNDLE_ENGINE.json +print_requests.py //serving-endpoints | gron.py --sort-arrays access_control_list > out.second-requests.$DATABRICKS_BUNDLE_ENGINE.txt echo "$ENDPOINT_NAME:ENDPOINT_NAME_2" >> ACC_REPLS