Skip to content

Commit 9cb6421

Browse files
committed
chore: add database methods for editing the default workspace proxy
1 parent 72f5995 commit 9cb6421

File tree

12 files changed

+211
-13
lines changed

12 files changed

+211
-13
lines changed

coderd/database/dbauthz/querier.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,11 @@ func (q *querier) DeleteLicense(ctx context.Context, id int32) (int32, error) {
369369
return id, nil
370370
}
371371

372+
func (q *querier) GetDefaultProxyConfig(ctx context.Context) (database.GetDefaultProxyConfigRow, error) {
373+
// No authz checks
374+
return q.db.GetDefaultProxyConfig(ctx)
375+
}
376+
372377
func (q *querier) GetDeploymentID(ctx context.Context) (string, error) {
373378
// No authz checks
374379
return q.db.GetDeploymentID(ctx)

coderd/database/dbauthz/querier_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,9 @@ func (s *MethodTestSuite) TestLicense() {
335335
s.Run("GetDeploymentID", s.Subtest(func(db database.Store, check *expects) {
336336
check.Args().Asserts().Returns("")
337337
}))
338+
s.Run("GetDefaultProxyConfig", s.Subtest(func(db database.Store, check *expects) {
339+
check.Args().Asserts().Returns(database.GetDefaultProxyConfigRow{})
340+
}))
338341
s.Run("GetLogoURL", s.Subtest(func(db database.Store, check *expects) {
339342
err := db.UpsertLogoURL(context.Background(), "value")
340343
require.NoError(s.T(), err)

coderd/database/dbauthz/system.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,3 +431,10 @@ func (q *querier) GetWorkspaceProxyByHostname(ctx context.Context, params databa
431431
}
432432
return q.db.GetWorkspaceProxyByHostname(ctx, params)
433433
}
434+
435+
func (q *querier) UpsertDefaultProxy(ctx context.Context, arg database.UpsertDefaultProxyParams) error {
436+
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceSystem); err != nil {
437+
return err
438+
}
439+
return q.db.UpsertDefaultProxy(ctx, arg)
440+
}

coderd/database/dbauthz/system_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ func (s *MethodTestSuite) TestSystemFunctions() {
2525
LoginType: database.LoginTypeGithub,
2626
}).Asserts(rbac.ResourceSystem, rbac.ActionUpdate).Returns(l)
2727
}))
28+
s.Run("UpsertDefaultProxy", s.Subtest(func(db database.Store, check *expects) {
29+
check.Args(database.UpsertDefaultProxyParams{}).Asserts(rbac.ResourceSystem, rbac.ActionUpdate).Returns()
30+
}))
2831
s.Run("GetUserLinkByLinkedID", s.Subtest(func(db database.Store, check *expects) {
2932
l := dbgen.UserLink(s.T(), db, database.UserLink{})
3033
check.Args(l.LinkedID).Asserts(rbac.ResourceSystem, rbac.ActionRead).Returns(l)

coderd/database/dbfake/databasefake.go

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ var errDuplicateKey = &pq.Error{
4141

4242
// New returns an in-memory fake of the database.
4343
func New() database.Store {
44-
return &fakeQuerier{
44+
q := &fakeQuerier{
4545
mutex: &sync.RWMutex{},
4646
data: &data{
4747
apiKeys: make([]database.APIKey, 0),
@@ -73,6 +73,9 @@ func New() database.Store {
7373
locks: map[int64]struct{}{},
7474
},
7575
}
76+
q.defaultProxyDisplayName = "Default"
77+
q.defaultProxyIconURL = "/emojis/1f3e1.png"
78+
return q
7679
}
7780

7881
type rwMutex interface {
@@ -144,14 +147,16 @@ type data struct {
144147

145148
// Locks is a map of lock names. Any keys within the map are currently
146149
// locked.
147-
locks map[int64]struct{}
148-
deploymentID string
149-
derpMeshKey string
150-
lastUpdateCheck []byte
151-
serviceBanner []byte
152-
logoURL string
153-
appSecurityKey string
154-
lastLicenseID int32
150+
locks map[int64]struct{}
151+
deploymentID string
152+
derpMeshKey string
153+
lastUpdateCheck []byte
154+
serviceBanner []byte
155+
logoURL string
156+
appSecurityKey string
157+
lastLicenseID int32
158+
defaultProxyDisplayName string
159+
defaultProxyIconURL string
155160
}
156161

157162
func validateDatabaseTypeWithValid(v reflect.Value) (handled bool, err error) {
@@ -5170,3 +5175,16 @@ func isNull(v interface{}) bool {
51705175
func isNotNull(v interface{}) bool {
51715176
return reflect.ValueOf(v).FieldByName("Valid").Bool()
51725177
}
5178+
5179+
func (q *fakeQuerier) GetDefaultProxyConfig(ctx context.Context) (database.GetDefaultProxyConfigRow, error) {
5180+
return database.GetDefaultProxyConfigRow{
5181+
DisplayName: q.defaultProxyDisplayName,
5182+
IconUrl: q.defaultProxyIconURL,
5183+
}, nil
5184+
}
5185+
5186+
func (q *fakeQuerier) UpsertDefaultProxy(ctx context.Context, arg database.UpsertDefaultProxyParams) error {
5187+
q.defaultProxyDisplayName = arg.DisplayName
5188+
q.defaultProxyIconURL = arg.IconUrl
5189+
return nil
5190+
}

coderd/database/dbmetrics/dbmetrics.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,3 +1518,17 @@ func (m metricsStore) GetAuthorizedUserCount(ctx context.Context, arg database.G
15181518
m.queryLatencies.WithLabelValues("GetAuthorizedUserCount").Observe(time.Since(start).Seconds())
15191519
return count, err
15201520
}
1521+
1522+
func (m metricsStore) UpsertDefaultProxy(ctx context.Context, arg database.UpsertDefaultProxyParams) error {
1523+
start := time.Now()
1524+
err := m.s.UpsertDefaultProxy(ctx, arg)
1525+
m.queryLatencies.WithLabelValues("UpsertDefaultProxy").Observe(time.Since(start).Seconds())
1526+
return err
1527+
}
1528+
1529+
func (m metricsStore) GetDefaultProxyConfig(ctx context.Context) (database.GetDefaultProxyConfigRow, error) {
1530+
start := time.Now()
1531+
resp, err := m.s.GetDefaultProxyConfig(ctx)
1532+
m.queryLatencies.WithLabelValues("GetDefaultProxyConfig").Observe(time.Since(start).Seconds())
1533+
return resp, err
1534+
}

coderd/database/dbmock/store.go

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/coder/coder/coderd/database"
1515
"github.com/coder/coder/coderd/database/dbgen"
1616
"github.com/coder/coder/coderd/database/migrations"
17+
"github.com/coder/coder/testutil"
1718
)
1819

1920
func TestGetDeploymentWorkspaceAgentStats(t *testing.T) {
@@ -257,3 +258,57 @@ func TestProxyByHostname(t *testing.T) {
257258
})
258259
}
259260
}
261+
262+
func TestDefaultProxy(t *testing.T) {
263+
t.Parallel()
264+
if testing.Short() {
265+
t.SkipNow()
266+
}
267+
sqlDB := testSQLDB(t)
268+
err := migrations.Up(sqlDB)
269+
require.NoError(t, err)
270+
db := database.New(sqlDB)
271+
272+
ctx := testutil.Context(t, testutil.WaitLong)
273+
depID := uuid.NewString()
274+
err = db.InsertDeploymentID(ctx, depID)
275+
require.NoError(t, err, "insert deployment id")
276+
277+
// Fetch empty proxy values
278+
defProxy, err := db.GetDefaultProxyConfig(ctx)
279+
require.NoError(t, err, "get def proxy")
280+
281+
require.Equal(t, defProxy.DisplayName, "Default")
282+
require.Equal(t, defProxy.IconUrl, "/emojis/1f3e1.png")
283+
284+
// Set the proxy values
285+
args := database.UpsertDefaultProxyParams{
286+
DisplayName: "displayname",
287+
IconUrl: "/icon.png",
288+
}
289+
err = db.UpsertDefaultProxy(ctx, args)
290+
require.NoError(t, err, "insert def proxy")
291+
292+
defProxy, err = db.GetDefaultProxyConfig(ctx)
293+
require.NoError(t, err, "get def proxy")
294+
require.Equal(t, defProxy.DisplayName, args.DisplayName)
295+
require.Equal(t, defProxy.IconUrl, args.IconUrl)
296+
297+
// Upsert values
298+
args = database.UpsertDefaultProxyParams{
299+
DisplayName: "newdisplayname",
300+
IconUrl: "/newicon.png",
301+
}
302+
err = db.UpsertDefaultProxy(ctx, args)
303+
require.NoError(t, err, "upsert def proxy")
304+
305+
defProxy, err = db.GetDefaultProxyConfig(ctx)
306+
require.NoError(t, err, "get def proxy")
307+
require.Equal(t, defProxy.DisplayName, args.DisplayName)
308+
require.Equal(t, defProxy.IconUrl, args.IconUrl)
309+
310+
// Ensure other site configs are the same
311+
found, err := db.GetDeploymentID(ctx)
312+
require.NoError(t, err, "get deployment id")
313+
require.Equal(t, depID, found)
314+
}

coderd/database/queries.sql.go

Lines changed: 41 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/siteconfig.sql

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
-- name: UpsertDefaultProxy :exec
2+
-- The default proxy is implied and not actually stored in the database.
3+
-- So we need to store it's configuration here for display purposes.
4+
-- The functional values are immutable and controlled implicitly.
5+
INSERT INTO site_configs (key, value)
6+
VALUES
7+
('default_proxy_display_name', @display_name :: text),
8+
('default_proxy_icon_url', @icon_url :: text)
9+
ON CONFLICT
10+
(key)
11+
DO UPDATE SET value = EXCLUDED.value WHERE site_configs.key = EXCLUDED.key
12+
;
13+
14+
-- name: GetDefaultProxyConfig :one
15+
SELECT
16+
COALESCE((SELECT value FROM site_configs WHERE key = 'default_proxy_display_name'), 'Default') :: text AS display_name,
17+
COALESCE((SELECT value FROM site_configs WHERE key = 'default_proxy_icon_url'), '/emojis/1f3e1.png') :: text AS icon_url
18+
;
19+
20+
121
-- name: InsertDeploymentID :exec
222
INSERT INTO site_configs (key, value) VALUES ('deployment_id', $1);
323

coderd/workspaceproxies.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,10 @@ func (api *API) PrimaryRegion(ctx context.Context) (codersdk.Region, error) {
2929
}
3030

3131
return codersdk.Region{
32-
ID: deploymentID,
33-
// TODO: provide some way to customize these fields for the primary
34-
// region
32+
ID: deploymentID,
3533
Name: "primary",
3634
DisplayName: "Default",
37-
IconURL: "/emojis/1f60e.png", // face with sunglasses
35+
IconURL: "/emojis/1f3e1.png", // House with garden
3836
Healthy: true,
3937
PathAppURL: api.AccessURL.String(),
4038
WildcardHostname: api.AppHostname,

0 commit comments

Comments
 (0)