Skip to content

Commit 689a9d4

Browse files
Remove parameter overrides from postgres commands (#501)
Removes all references to parameter overrides from Postgres commands This is essentially a boundary-level concern: - Remove the CLI flag for `--parameter-override` - Nil out `ParameterOverrides` map on the output structs, so that when we serialize to JSON omit it entirely - For text-based output, stop outputting the parameter overrides Letting users override parameters in Render Postgres is built out but very early access and only available to a few customers. Bel asked me to hide the concept from the CLI. GROW-2618 GitOrigin-RevId: 9210e5c463c9054075b9ab186b771bb57f95b512
1 parent 61767d8 commit 689a9d4

20 files changed

Lines changed: 98 additions & 316 deletions

cmd/pgcreate.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ func newPgCreateCmd(deps *dependencies.Dependencies) *cobra.Command {
2525
2626
In interactive mode, a wizard guides you through the core choices for the
2727
database. The wizard owns those prompted values. Flag-only settings, such as
28-
--disk-size-gb, --database-name, --database-user, --ip-allow-list,
29-
--parameter-override, and --read-replica, are still included in the create
30-
request.
28+
--disk-size-gb, --database-name, --database-user, --ip-allow-list, and --read-replica,
29+
are still included in the create request.
3130
3231
Use --confirm to skip the wizard and create immediately from flags and defaults.
3332
When --confirm is used with the default interactive output mode, output is
@@ -76,10 +75,6 @@ Examples:
7675
cmd.Flags().StringArray("ip-allow-list", nil,
7776
"Restrict inbound traffic to specific IP ranges. Repeat the flag for multiple entries.\n"+
7877
"Format: cidr=<range>,description=<label>")
79-
cmd.Flags().StringArray("parameter-override", nil,
80-
"Override a Postgres server parameter. Repeat the flag for multiple entries.\n"+
81-
"Format: KEY=VALUE\n"+
82-
"Example: --parameter-override max_connections=100")
8378
cmd.Flags().StringArray("read-replica", nil,
8479
"Name of a read replica to create alongside the primary. Repeat the flag for multiple replicas.")
8580

cmd/pgcreate_test.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ func TestPGCreate_AllFlags(t *testing.T) {
5151
"--datadog-api-key", "dd-key",
5252
"--datadog-site", "US3",
5353
"--ip-allow-list", "cidr=10.0.0.0/8,description=internal",
54-
"--parameter-override", "max_connections=111",
5554
"--read-replica", "analytics-replica-1",
5655
"--output", "text",
5756
)
@@ -74,8 +73,7 @@ func TestPGCreate_AllFlags(t *testing.T) {
7473
assert.Equal(t, "internal", pg.IpAllowList[0].Description)
7574
require.Len(t, pg.ReadReplicas, 1)
7675
assert.Equal(t, "analytics-replica-1", pg.ReadReplicas[0].Name)
77-
require.NotNil(t, pg.ParameterOverrides)
78-
assert.Equal(t, "111", (*pg.ParameterOverrides)["max_connections"])
76+
assert.Nil(t, pg.ParameterOverrides)
7977
assert.Contains(t, result.Stdout, "analytics")
8078
assert.Contains(t, result.Stdout, "Read replicas:")
8179
}
@@ -144,15 +142,15 @@ func TestPGCreate_PostgresAlias(t *testing.T) {
144142
assert.Equal(t, "alias-pg", server.Postgres.Instances[0].Name)
145143
}
146144

147-
func TestPGCreate_InvalidParameterOverride(t *testing.T) {
145+
func TestPGCreate_ParameterOverrideFlagIsUnknown(t *testing.T) {
148146
server := renderapi.NewServer(t)
149147
result, err := executePGCreate(t, server,
150-
"--parameter-override", "noequals",
148+
"--parameter-override", "max_connections=111",
151149
"--output", "text",
152150
)
153151
require.Error(t, err)
154152

155-
assert.Contains(t, result.Stderr, "expected KEY=VALUE format")
153+
assert.Contains(t, result.Stderr, "unknown flag: --parameter-override")
156154
assert.Empty(t, server.Postgres.Instances)
157155
}
158156

cmd/pgupdate.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,6 @@ mutually exclusive.`,
7676
cmd.Flags().String("datadog-api-key", "", "Datadog API key for monitoring. Pass an empty string to remove.")
7777
cmd.Flags().String("datadog-site", "", "Datadog region/site (e.g. US1, US3, EU)")
7878

79-
cmd.Flags().StringArray("parameter-override", nil,
80-
"Override a Postgres server parameter. Repeat the flag for multiple entries.\n"+
81-
"Format: KEY=VALUE\n"+
82-
"Example: --parameter-override max_connections=100\n\n"+
83-
"Entries not mentioned in the flag are preserved (upsert semantics — keys\n"+
84-
"you supply are added or updated; all other existing overrides are kept).\n"+
85-
"To remove an individual override, use the Render dashboard.")
8679
cmd.Flags().StringArray("ip-allow-list", nil,
8780
"Replace the IP allow-list with the supplied entries. Repeat the flag for multiple entries.\n"+
8881
"Format: cidr=<range>,description=<label>")

cmd/pgupdate_test.go

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -205,35 +205,13 @@ func TestPGUpdate_NoMutationFields_Errors(t *testing.T) {
205205
assert.Contains(t, err.Error(), "at least one field")
206206
}
207207

208-
func TestPGUpdate_ParameterOverrideUpsert(t *testing.T) {
209-
harness := newPGUpdateHarness(t)
210-
existing := client.PostgresParameterOverrides{"work_mem": "64MB", "max_connections": "100"}
211-
pg := harness.server.Postgres.Add(renderapi.NewPostgres(client.PostgresDetail{
212-
Name: "param-db",
213-
Owner: client.Owner{Id: pgActiveWorkspaceID},
214-
ParameterOverrides: &existing,
215-
}))
216-
217-
_, err := harness.execute(pg.Id,
218-
"--parameter-override", "max_connections=200",
219-
"--parameter-override", "lock_timeout=5000",
220-
"--output", "text")
221-
require.NoError(t, err)
222-
223-
require.NotNil(t, pg.ParameterOverrides)
224-
overrides := *pg.ParameterOverrides
225-
assert.Equal(t, "200", overrides["max_connections"], "supplied key should be updated")
226-
assert.Equal(t, "5000", overrides["lock_timeout"], "new key should be added")
227-
assert.Equal(t, "64MB", overrides["work_mem"], "unsupplied key should be preserved")
228-
}
229-
230-
func TestPGUpdate_BadParameterOverride_Errors(t *testing.T) {
208+
func TestPGUpdate_ParameterOverrideFlagIsUnknown(t *testing.T) {
231209
harness := newPGUpdateHarness(t)
232210
pg := seedPG(harness.server, "my-db")
233211

234-
_, err := harness.execute(pg.Id, "--parameter-override", "noequals", "--output", "text")
212+
result, err := harness.execute(pg.Id, "--parameter-override", "max_connections=111", "--output", "text")
235213
require.Error(t, err)
236-
assert.Contains(t, err.Error(), "expected KEY=VALUE format")
214+
assert.Contains(t, result.Stderr, "unknown flag: --parameter-override")
237215
}
238216

239217
func TestPGUpdate_BothIPAllowListAndClearFlags_Errors(t *testing.T) {

pkg/postgres/create.go

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,21 @@ const DefaultPostgresVersion = 18
2525
// All client-side defaults have been applied and the scope has been resolved to an owner
2626
// ID + optional environment ID by the time this struct is constructed.
2727
type CreateRequestInput struct {
28-
Name string
29-
OwnerID string
30-
Plan string
31-
Version int
32-
Region *string
33-
EnvironmentID *string
34-
DatabaseName *string
35-
DatabaseUser *string
36-
HighAvailability *bool
37-
DiskSizeGB *int
38-
DiskAutoscaling *bool
39-
DatadogAPIKey *string
40-
DatadogSite *string
41-
IPAllowList []string
42-
ParameterOverrides []string
43-
ReadReplicas []string
28+
Name string
29+
OwnerID string
30+
Plan string
31+
Version int
32+
Region *string
33+
EnvironmentID *string
34+
DatabaseName *string
35+
DatabaseUser *string
36+
HighAvailability *bool
37+
DiskSizeGB *int
38+
DiskAutoscaling *bool
39+
DatadogAPIKey *string
40+
DatadogSite *string
41+
IPAllowList []string
42+
ReadReplicas []string
4443
}
4544

4645
// buildRequestInput applies defaults to CLI input and produces the resolved
@@ -59,22 +58,21 @@ func buildRequestInput(in pgtypes.CreatePostgresInput, ownerID string, environme
5958
version = *in.Version
6059
}
6160
return CreateRequestInput{
62-
Name: name,
63-
OwnerID: ownerID,
64-
Plan: plan,
65-
Version: version,
66-
Region: in.Region,
67-
EnvironmentID: environmentID,
68-
DatabaseName: in.DatabaseName,
69-
DatabaseUser: in.DatabaseUser,
70-
HighAvailability: in.HighAvailability,
71-
DiskSizeGB: in.DiskSizeGB,
72-
DiskAutoscaling: in.DiskAutoscaling,
73-
DatadogAPIKey: in.DatadogAPIKey,
74-
DatadogSite: in.DatadogSite,
75-
IPAllowList: in.IPAllowList,
76-
ParameterOverrides: in.ParameterOverrides,
77-
ReadReplicas: in.ReadReplicas,
61+
Name: name,
62+
OwnerID: ownerID,
63+
Plan: plan,
64+
Version: version,
65+
Region: in.Region,
66+
EnvironmentID: environmentID,
67+
DatabaseName: in.DatabaseName,
68+
DatabaseUser: in.DatabaseUser,
69+
HighAvailability: in.HighAvailability,
70+
DiskSizeGB: in.DiskSizeGB,
71+
DiskAutoscaling: in.DiskAutoscaling,
72+
DatadogAPIKey: in.DatadogAPIKey,
73+
DatadogSite: in.DatadogSite,
74+
IPAllowList: in.IPAllowList,
75+
ReadReplicas: in.ReadReplicas,
7876
}
7977
}
8078

@@ -98,11 +96,6 @@ func BuildCreateRequest(input CreateRequestInput) (client.CreatePostgresJSONRequ
9896
return client.CreatePostgresJSONRequestBody{}, err
9997
}
10098

101-
paramOverrides, err := buildParameterOverrides(input.ParameterOverrides)
102-
if err != nil {
103-
return client.CreatePostgresJSONRequestBody{}, err
104-
}
105-
10699
body := client.CreatePostgresJSONRequestBody{
107100
Name: input.Name,
108101
OwnerId: input.OwnerID,
@@ -116,7 +109,6 @@ func BuildCreateRequest(input CreateRequestInput) (client.CreatePostgresJSONRequ
116109
EnableDiskAutoscaling: input.DiskAutoscaling,
117110
EnableHighAvailability: input.HighAvailability,
118111
EnvironmentId: input.EnvironmentID,
119-
ParameterOverrides: paramOverrides,
120112
ReadReplicas: buildReadReplicas(input.ReadReplicas),
121113
}
122114

pkg/postgres/create_test.go

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -105,50 +105,7 @@ func TestBuildCreateRequest_AllFieldsSpecified(t *testing.T) {
105105
assert.Equal(t, "internal", (*body.IpAllowList)[0].Description)
106106
assert.Equal(t, "203.0.113.5/32", (*body.IpAllowList)[1].CidrBlock)
107107
assert.Equal(t, "office", (*body.IpAllowList)[1].Description)
108-
}
109-
110-
func TestBuildCreateRequest_ParameterOverrides(t *testing.T) {
111-
t.Run("parses KEY=VALUE pairs and trims whitespace", func(t *testing.T) {
112-
in := minimalInput()
113-
in.ParameterOverrides = []string{"max_connections=100", " shared_buffers = 256MB "}
114-
body, err := postgres.BuildCreateRequest(in)
115-
require.NoError(t, err)
116-
require.NotNil(t, body.ParameterOverrides)
117-
assert.Equal(t, "100", (*body.ParameterOverrides)["max_connections"])
118-
assert.Equal(t, "256MB", (*body.ParameterOverrides)["shared_buffers"])
119-
})
120-
121-
t.Run("rejects when any entry is malformed", func(t *testing.T) {
122-
in := minimalInput()
123-
in.ParameterOverrides = []string{"max_connections=100", "noequals", "shared_buffers=256MB"}
124-
_, err := postgres.BuildCreateRequest(in)
125-
require.Error(t, err)
126-
assert.Contains(t, err.Error(), `"noequals"`)
127-
})
128-
129-
t.Run("rejects malformed entries", func(t *testing.T) {
130-
cases := []struct {
131-
name string
132-
entry string
133-
}{
134-
{"no equals sign", "noequals"},
135-
{"empty string", ""},
136-
{"missing key (=VALUE)", "=value"},
137-
{"missing value (KEY=)", "max_connections="},
138-
{"both sides empty (=)", "="},
139-
{"whitespace-only key", " =value"},
140-
{"whitespace-only value", "max_connections= "},
141-
}
142-
for _, tc := range cases {
143-
t.Run(tc.name, func(t *testing.T) {
144-
in := minimalInput()
145-
in.ParameterOverrides = []string{tc.entry}
146-
_, err := postgres.BuildCreateRequest(in)
147-
require.Error(t, err)
148-
assert.Contains(t, err.Error(), "KEY=VALUE")
149-
})
150-
}
151-
})
108+
assert.Nil(t, body.ParameterOverrides)
152109
}
153110

154111
func TestBuildCreateRequest_ReadReplicas(t *testing.T) {

pkg/postgres/output.go

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package postgres
22

33
import (
4-
"reflect"
5-
64
"github.com/render-oss/cli/internal/ipallowlist"
75
"github.com/render-oss/cli/pkg/client"
86
pgclient "github.com/render-oss/cli/pkg/client/postgres"
@@ -64,13 +62,12 @@ type PostgresUpdateOut struct {
6462
}
6563

6664
type PostgresUpdateDiff struct {
67-
Name *PostgresFieldDiff[string] `json:"name,omitempty"`
68-
Plan *PostgresFieldDiff[pgclient.PostgresPlans] `json:"plan,omitempty"`
69-
DiskSizeGB *PostgresFieldDiff[*int] `json:"diskSizeGB,omitempty"`
70-
DiskAutoscalingEnabled *PostgresFieldDiff[bool] `json:"diskAutoscalingEnabled,omitempty"`
71-
HighAvailabilityEnabled *PostgresFieldDiff[bool] `json:"highAvailabilityEnabled,omitempty"`
72-
IPAllowList *PostgresFieldDiff[[]client.CidrBlockAndDescription] `json:"ipAllowList,omitempty"`
73-
ParameterOverrides *PostgresFieldDiff[*client.PostgresParameterOverrides] `json:"parameterOverrides,omitempty"`
65+
Name *PostgresFieldDiff[string] `json:"name,omitempty"`
66+
Plan *PostgresFieldDiff[pgclient.PostgresPlans] `json:"plan,omitempty"`
67+
DiskSizeGB *PostgresFieldDiff[*int] `json:"diskSizeGB,omitempty"`
68+
DiskAutoscalingEnabled *PostgresFieldDiff[bool] `json:"diskAutoscalingEnabled,omitempty"`
69+
HighAvailabilityEnabled *PostgresFieldDiff[bool] `json:"highAvailabilityEnabled,omitempty"`
70+
IPAllowList *PostgresFieldDiff[[]client.CidrBlockAndDescription] `json:"ipAllowList,omitempty"`
7471
}
7572

7673
type PostgresFieldDiff[T any] struct {
@@ -160,14 +157,6 @@ func newPostgresUpdateDiff(before *client.PostgresDetail, after *PostgresOut) Po
160157
if !ipallowlist.Equal(before.IpAllowList, after.IpAllowList) {
161158
diff.IPAllowList = newPostgresFieldDiff(before.IpAllowList, after.IpAllowList)
162159
}
163-
beforeOverrides := normalizePostgresParameterOverrides(before.ParameterOverrides)
164-
afterOverrides := normalizePostgresParameterOverrides(after.ParameterOverrides)
165-
if !reflect.DeepEqual(beforeOverrides, afterOverrides) {
166-
diff.ParameterOverrides = newPostgresFieldDiff(
167-
beforeOverrides,
168-
afterOverrides,
169-
)
170-
}
171160
return diff
172161
}
173162

@@ -194,9 +183,10 @@ func finalizePostgresOut(out *PostgresOut, project *client.Project, env *client.
194183
if out.ReadReplicas == nil {
195184
out.ReadReplicas = client.ReadReplicas{}
196185
}
197-
if out.ParameterOverrides != nil && len(*out.ParameterOverrides) == 0 {
198-
out.ParameterOverrides = nil
199-
}
186+
// Parameter overrides are still early in rollout, so keep them out of
187+
// CLI-facing output even when the API/client type carries populated values.
188+
out.ParameterOverrides = nil
189+
hideReadReplicaParameterOverrides(out.ReadReplicas)
200190
if env != nil {
201191
out.EnvironmentId = &env.Id
202192
out.EnvironmentName = env.Name
@@ -214,6 +204,7 @@ func finalizePostgresListItemOut(out *PostgresListItemOut, project *client.Proje
214204
if out.ReadReplicas == nil {
215205
out.ReadReplicas = client.ReadReplicas{}
216206
}
207+
hideReadReplicaParameterOverrides(out.ReadReplicas)
217208
if env != nil {
218209
out.EnvironmentId = &env.Id
219210
out.EnvironmentName = env.Name
@@ -231,9 +222,10 @@ func newPostgresFieldDiff[T any](before, after T) *PostgresFieldDiff[T] {
231222
}
232223
}
233224

234-
func normalizePostgresParameterOverrides(overrides *client.PostgresParameterOverrides) *client.PostgresParameterOverrides {
235-
if overrides == nil || len(*overrides) == 0 {
236-
return nil
225+
func hideReadReplicaParameterOverrides(replicas client.ReadReplicas) {
226+
// Read replicas share the same early-rollout parameter override field, so
227+
// omit it from list/detail output until the feature is generally available.
228+
for i := range replicas {
229+
replicas[i].ParameterOverrides = nil
237230
}
238-
return overrides
239231
}

pkg/postgres/output_test.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ func TestNewPostgresListOut_ConstructsItems(t *testing.T) {
5353

5454
expectedPostgres := *pg
5555
expectedPostgres.IpAllowList = []client.CidrBlockAndDescription{}
56+
expectedPostgres.ReadReplicas[0].ParameterOverrides = nil
5657
assert.Equal(t, expectedPostgres, out.Data[0].Postgres)
5758
assert.Equal(t, pointers.From("prj-prod"), out.Data[0].ProjectID)
5859
assert.Equal(t, "Production Project", out.Data[0].ProjectName)
@@ -132,13 +133,12 @@ func TestNewPostgresGetOut_JSONSerialization(t *testing.T) {
132133
"diskAutoscalingEnabled": true,
133134
"highAvailabilityEnabled": true,
134135
"ipAllowList": []any{map[string]any{"cidrBlock": "203.0.113.5/32", "description": "office"}},
135-
"readReplicas": []any{map[string]any{"id": "dpg-replica", "name": "analytics-replica", "parameterOverrides": map[string]any{"work_mem": "64MB"}}},
136+
"readReplicas": []any{map[string]any{"id": "dpg-replica", "name": "analytics-replica"}},
136137
"primaryPostgresID": "dpg-primary",
137138
"role": "primary",
138139
"suspended": "not_suspended",
139140
"suspenders": []any{},
140141
"dashboardUrl": "https://dashboard.render.com/d/dpg-detail",
141-
"parameterOverrides": map[string]any{"max_connections": "100"},
142142
"connectionInfo": map[string]any{
143143
"psqlCommand": "psql postgres://example",
144144
"internalConnectionString": "postgres://internal",
@@ -300,11 +300,9 @@ func TestNewPostgresUpdateOut(t *testing.T) {
300300
"before": []any{map[string]any{"cidrBlock": "203.0.113.5/32", "description": "office"}},
301301
"after": []any{},
302302
},
303-
"parameterOverrides": map[string]any{
304-
"before": map[string]any{"max_connections": "100"},
305-
"after": map[string]any{"max_connections": "200"},
306-
},
307303
}, diff)
304+
assert.NotContains(t, body, "parameterOverrides")
305+
assert.NotContains(t, testrequire.SubMap(t, body, "data"), "parameterOverrides")
308306
}
309307

310308
func marshalJSONMap(t *testing.T, v any) map[string]any {

0 commit comments

Comments
 (0)