Skip to content

Commit 68d1b9f

Browse files
pieterndenik
authored andcommitted
postgres: read ids from Status instead of parsing Name (#5274)
The Postgres GET API now echoes the leaf id on the Status payload (`BranchStatus.BranchId`, `EndpointStatus.EndpointId`, `ProjectStatus.ProjectId`). Drop the regex-based `ParsePostgresName` recovery in the three `make*Remote` helpers and read the id directly from Status. The component helper and its unit test go with it; the one remaining call site in `all_test.go` now uses the project id literal it just created. Fields added in SDK v0.129.0 (databricks/databricks-sdk-go#1644); available in the CLI since #5237 bumped the SDK to v0.132.0. The testserver was taught to populate these fields in the companion PR #5246, so local acceptance fixtures are unchanged. Stacked on #5273 — base will retarget to `main` once that merges. This pull request and its description were written by Isaac.
1 parent db842e1 commit 68d1b9f

6 files changed

Lines changed: 19 additions & 139 deletions

File tree

bundle/direct/dresources/all_test.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -417,20 +417,19 @@ var testDeps = map[string]prepareWorkspace{
417417
},
418418

419419
"postgres_projects.permissions": func(ctx context.Context, client *databricks.WorkspaceClient) (any, error) {
420+
const projectID = "permissions-project"
420421
waiter, err := client.Postgres.CreateProject(ctx, postgres.CreateProjectRequest{
421-
ProjectId: "permissions-project",
422+
ProjectId: projectID,
422423
})
423424
if err != nil {
424425
return nil, err
425426
}
426-
result, err := waiter.Wait(ctx)
427-
if err != nil {
427+
if _, err := waiter.Wait(ctx); err != nil {
428428
return nil, err
429429
}
430430

431-
components, _ := ParsePostgresName(result.Name)
432431
return &PermissionsState{
433-
ObjectID: "/database-projects/" + components.ProjectID,
432+
ObjectID: "/database-projects/" + projectID,
434433
EmbeddedSlice: []StatePermission{{
435434
Level: "CAN_MANAGE",
436435
UserName: "user@example.com",

bundle/direct/dresources/postgres_branch.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,17 @@ func (*ResourcePostgresBranch) RemapState(remote *PostgresBranchRemote) *Postgre
7474
// stay at their zero values, and resources.yml suppresses phantom drift via
7575
// ignore_remote_changes with reason spec:input_only.
7676
func makePostgresBranchRemote(branch *postgres.Branch) *PostgresBranchRemote {
77-
// Extract branch_id from hierarchical name: "projects/{project_id}/branches/{branch_id}"
78-
// TODO: log error when we have access to the context
79-
components, _ := ParsePostgresName(branch.Name)
8077
var spec postgres.BranchSpec
8178
if branch.Spec != nil {
8279
spec = *branch.Spec
8380
}
81+
var branchID string
82+
if branch.Status != nil {
83+
branchID = branch.Status.BranchId
84+
}
8485
return &PostgresBranchRemote{
8586
BranchSpec: spec,
86-
BranchId: components.BranchID,
87+
BranchId: branchID,
8788
Parent: branch.Parent,
8889
Name: branch.Name,
8990
Status: branch.Status,

bundle/direct/dresources/postgres_endpoint.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,17 @@ func (*ResourcePostgresEndpoint) RemapState(remote *PostgresEndpointRemote) *Pos
8383
// stay at their zero values, and resources.yml suppresses phantom drift via
8484
// ignore_remote_changes with reason spec:input_only.
8585
func makePostgresEndpointRemote(endpoint *postgres.Endpoint) *PostgresEndpointRemote {
86-
// Extract endpoint_id from hierarchical name: "projects/{project_id}/branches/{branch_id}/endpoints/{endpoint_id}"
87-
// TODO: log error when we have access to the context
88-
components, _ := ParsePostgresName(endpoint.Name)
8986
var spec postgres.EndpointSpec
9087
if endpoint.Spec != nil {
9188
spec = *endpoint.Spec
9289
}
90+
var endpointID string
91+
if endpoint.Status != nil {
92+
endpointID = endpoint.Status.EndpointId
93+
}
9394
return &PostgresEndpointRemote{
9495
EndpointSpec: spec,
95-
EndpointId: components.EndpointID,
96+
EndpointId: endpointID,
9697
Parent: endpoint.Parent,
9798
Name: endpoint.Name,
9899
Status: endpoint.Status,

bundle/direct/dresources/postgres_project.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,17 @@ func (*ResourcePostgresProject) RemapState(remote *PostgresProjectRemote) *Postg
6868
// stay at their zero values, and resources.yml suppresses phantom drift via
6969
// ignore_remote_changes with reason spec:input_only.
7070
func makePostgresProjectRemote(project *postgres.Project) *PostgresProjectRemote {
71-
// Extract project_id from hierarchical name: "projects/{project_id}"
72-
// TODO: log error when we have access to the context
73-
components, _ := ParsePostgresName(project.Name)
7471
var spec postgres.ProjectSpec
7572
if project.Spec != nil {
7673
spec = *project.Spec
7774
}
75+
var projectID string
76+
if project.Status != nil {
77+
projectID = project.Status.ProjectId
78+
}
7879
return &PostgresProjectRemote{
7980
ProjectSpec: spec,
80-
ProjectId: components.ProjectID,
81+
ProjectId: projectID,
8182
InitialEndpointSpec: project.InitialEndpointSpec,
8283
Name: project.Name,
8384
Status: project.Status,

bundle/direct/dresources/util.go

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,12 @@ package dresources
22

33
import (
44
"errors"
5-
"fmt"
6-
"regexp"
75

86
"github.com/databricks/cli/bundle/deployplan"
97
"github.com/databricks/cli/libs/structs/structpath"
108
"github.com/databricks/databricks-sdk-go/retries"
119
)
1210

13-
// postgresNamePattern matches hierarchical Postgres resource names:
14-
// - projects/{project_id}
15-
// - projects/{project_id}/branches/{branch_id}
16-
// - projects/{project_id}/branches/{branch_id}/endpoints/{endpoint_id}
17-
var postgresNamePattern = regexp.MustCompile(`^projects/([^/]+)(?:/branches/([^/]+)(?:/endpoints/([^/]+))?)?$`)
18-
19-
// PostgresNameComponents holds the extracted components from a Postgres resource name.
20-
type PostgresNameComponents struct {
21-
ProjectID string
22-
BranchID string
23-
EndpointID string
24-
}
25-
26-
// ParsePostgresName extracts project, branch, and endpoint IDs from a hierarchical Postgres resource name.
27-
// Returns an error if the name doesn't match the expected format.
28-
func ParsePostgresName(name string) (PostgresNameComponents, error) {
29-
matches := postgresNamePattern.FindStringSubmatch(name)
30-
if matches == nil {
31-
return PostgresNameComponents{}, fmt.Errorf("invalid postgres resource name format: %q", name)
32-
}
33-
34-
return PostgresNameComponents{
35-
ProjectID: matches[1],
36-
BranchID: matches[2],
37-
EndpointID: matches[3],
38-
}, nil
39-
}
40-
4111
// This is copied from the retries package of the databricks-sdk-go. It should be made public,
4212
// but for now, I'm copying it here.
4313
func shouldRetry(err error) bool {

bundle/direct/dresources/util_test.go

Lines changed: 0 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"testing"
66

77
"github.com/stretchr/testify/assert"
8-
"github.com/stretchr/testify/require"
98
)
109

1110
// assertFieldsCovered asserts that all fields in sdkType (except those in skip)
@@ -29,94 +28,3 @@ func assertFieldsCovered(t *testing.T, sdkType, remoteType reflect.Type, skip ma
2928
assert.Contains(t, remoteFields, field.Name, "field %s from %s is missing in %s", field.Name, sdkType.Name(), remoteType.Name())
3029
}
3130
}
32-
33-
func TestParsePostgresName(t *testing.T) {
34-
tests := []struct {
35-
name string
36-
input string
37-
projectID string
38-
branchID string
39-
endpointID string
40-
expectErr bool
41-
}{
42-
{
43-
name: "project",
44-
input: "projects/my-project",
45-
projectID: "my-project",
46-
},
47-
{
48-
name: "branch",
49-
input: "projects/my-project/branches/my-branch",
50-
projectID: "my-project",
51-
branchID: "my-branch",
52-
},
53-
{
54-
name: "endpoint",
55-
input: "projects/my-project/branches/my-branch/endpoints/my-endpoint",
56-
projectID: "my-project",
57-
branchID: "my-branch",
58-
endpointID: "my-endpoint",
59-
},
60-
{
61-
name: "with hyphens and numbers",
62-
input: "projects/my-app-123/branches/dev-branch/endpoints/primary-1",
63-
projectID: "my-app-123",
64-
branchID: "dev-branch",
65-
endpointID: "primary-1",
66-
},
67-
{
68-
name: "empty",
69-
input: "",
70-
expectErr: true,
71-
},
72-
{
73-
name: "no prefix",
74-
input: "my-project",
75-
expectErr: true,
76-
},
77-
{
78-
name: "wrong prefix",
79-
input: "project/my-project",
80-
expectErr: true,
81-
},
82-
{
83-
name: "missing branch id",
84-
input: "projects/my-project/branches/",
85-
expectErr: true,
86-
},
87-
{
88-
name: "missing endpoint id",
89-
input: "projects/my-project/branches/my-branch/endpoints/",
90-
expectErr: true,
91-
},
92-
{
93-
name: "extra segments",
94-
input: "projects/my-project/branches/my-branch/endpoints/my-endpoint/extra",
95-
expectErr: true,
96-
},
97-
{
98-
name: "branches without branch",
99-
input: "projects/my-project/branches",
100-
expectErr: true,
101-
},
102-
{
103-
name: "endpoints without endpoint",
104-
input: "projects/my-project/branches/my-branch/endpoints",
105-
expectErr: true,
106-
},
107-
}
108-
109-
for _, tt := range tests {
110-
t.Run(tt.name, func(t *testing.T) {
111-
components, err := ParsePostgresName(tt.input)
112-
if tt.expectErr {
113-
assert.ErrorContains(t, err, "invalid postgres resource name format")
114-
return
115-
}
116-
require.NoError(t, err)
117-
assert.Equal(t, tt.projectID, components.ProjectID)
118-
assert.Equal(t, tt.branchID, components.BranchID)
119-
assert.Equal(t, tt.endpointID, components.EndpointID)
120-
})
121-
}
122-
}

0 commit comments

Comments
 (0)