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
1 change: 1 addition & 0 deletions NEXT_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
### CLI

### Bundles
* Stop applying `presets.name_prefix` (and the dev-mode `[dev <user>]` rename) to `vector_search_endpoints` ([#5209](https://github.com/databricks/cli/pull/5209)).

### Dependency updates
10 changes: 3 additions & 7 deletions bundle/config/mutator/resourcemutator/apply_presets.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,13 +290,9 @@ func (m *applyPresets) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnos
}
}

// Vector Search Endpoints: Prefix
for _, e := range r.VectorSearchEndpoints {
if e == nil {
continue
}
e.Name = normalizePrefix(prefix) + e.Name
}
// Vector Search Endpoints: no prefix. The endpoint name is the primary key
// (it's what GET/UPDATE/DELETE address by), so prefixing it would change
// the resource's identity rather than just its display name.

return diags
}
Expand Down
70 changes: 41 additions & 29 deletions bundle/config/mutator/resourcemutator/apply_target_mode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,8 @@ func TestProcessTargetModeDevelopment(t *testing.T) {
// Model serving endpoint 1
assert.Equal(t, "dev_lennart_servingendpoint1", b.Config.Resources.ModelServingEndpoints["servingendpoint1"].Name)

// Vector search endpoint 1
assert.Equal(t, "dev_lennart_vs_endpoint1", b.Config.Resources.VectorSearchEndpoints["vs_endpoint1"].Name)
// Vector search endpoint 1: name is the primary key, so it must not be prefixed.
assert.Equal(t, "vs_endpoint1", b.Config.Resources.VectorSearchEndpoints["vs_endpoint1"].Name)

// Registered model 1
assert.Equal(t, "dev_lennart_registeredmodel1", b.Config.Resources.RegisteredModels["registeredmodel1"].Name)
Expand Down Expand Up @@ -414,17 +414,33 @@ func TestAllResourcesMocked(t *testing.T) {
}
}

// Make sure that we at rename all non UC resources
func TestAllNonUcResourcesAreRenamed(t *testing.T) {
// TestAppropriateResourcesAreRenamed checks that every resource with a user-facing
// Name field is renamed by dev-mode / presets.name_prefix, except for an
// explicit carve-out list. The carve-out applies to resources whose Name is
// the API primary key / object id (not a display name) — prefixing those
// would change the resource's identity rather than its label.
func TestAppropriateResourcesAreRenamed(t *testing.T) {
b := mockBundle(config.Development)

// UC resources should not have a prefix added to their name. Right now
// this list only contains the Volume, Catalog, and ExternalLocation resources since we have yet to remove
// prefixing support for UC schemas and registered models.
ucFields := []reflect.Type{
notRenamedFields := []reflect.Type{
reflect.TypeFor[*resources.Catalog](),
reflect.TypeFor[*resources.ExternalLocation](),
reflect.TypeFor[*resources.Volume](),
reflect.TypeFor[*resources.VectorSearchEndpoint](),
}

// Resources whose Name is server-generated or otherwise not a user-facing
// label, so the rename matrix doesn't apply. Reflection still finds a
// Name field on these via embedded SDK types, hence the explicit skip.
notUserNamed := []string{
"Apps",
"SecretScopes",
"DatabaseInstances",
"DatabaseCatalogs",
"SyncedDatabaseTables",
"PostgresProjects",
"PostgresBranches",
"PostgresEndpoints",
}

diags := bundle.ApplySeq(t.Context(), b, ApplyTargetMode(), ApplyPresets())
Expand All @@ -433,28 +449,24 @@ func TestAllNonUcResourcesAreRenamed(t *testing.T) {
resources := reflect.ValueOf(b.Config.Resources)
for i := range resources.NumField() {
field := resources.Field(i)
if field.Kind() != reflect.Map {
continue
}
resourceType := resources.Type().Field(i).Name
if slices.Contains(notUserNamed, resourceType) {
continue
}
for _, key := range field.MapKeys() {
resource := field.MapIndex(key)
nameField := resource.Elem().FieldByName("Name")
if !nameField.IsValid() || nameField.Kind() != reflect.String {
continue
}

if field.Kind() == reflect.Map {
for _, key := range field.MapKeys() {
resource := field.MapIndex(key)
nameField := resource.Elem().FieldByName("Name")
resourceType := resources.Type().Field(i).Name

// Skip resources that are not renamed (either because they don't have a user-facing Name field,
// or because their Name is server-generated rather than user-specified)
if resourceType == "Apps" || resourceType == "SecretScopes" || resourceType == "DatabaseInstances" || resourceType == "DatabaseCatalogs" || resourceType == "SyncedDatabaseTables" || resourceType == "PostgresProjects" || resourceType == "PostgresBranches" || resourceType == "PostgresEndpoints" {
continue
}

if !nameField.IsValid() || nameField.Kind() != reflect.String {
continue
}

if slices.Contains(ucFields, resource.Type()) {
assert.NotContains(t, nameField.String(), "dev", "process_target_mode should not rename '%s' in '%s'", key, resources.Type().Field(i).Name)
} else {
assert.Contains(t, nameField.String(), "dev", "process_target_mode should rename '%s' in '%s'", key, resources.Type().Field(i).Name)
}
if slices.Contains(notRenamedFields, resource.Type()) {
assert.NotContains(t, nameField.String(), "dev", "process_target_mode should not rename '%s' in '%s'", key, resourceType)
} else {
assert.Contains(t, nameField.String(), "dev", "process_target_mode should rename '%s' in '%s'", key, resourceType)
}
}
}
Expand Down
Loading