Skip to content

Commit 335eb05

Browse files
authored
feat: add keys to organization provision daemons (coder#14627)
1 parent 4afce19 commit 335eb05

32 files changed

+728
-72
lines changed

coderd/apidoc/docs.go

+55
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

+51
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/coderd.go

+6
Original file line numberDiff line numberDiff line change
@@ -1491,6 +1491,11 @@ func (api *API) CreateInMemoryTaggedProvisionerDaemon(dialCtx context.Context, n
14911491
dbTypes = append(dbTypes, database.ProvisionerType(tp))
14921492
}
14931493

1494+
keyID, err := uuid.Parse(string(codersdk.ProvisionerKeyIDBuiltIn))
1495+
if err != nil {
1496+
return nil, xerrors.Errorf("failed to parse built-in provisioner key ID: %w", err)
1497+
}
1498+
14941499
//nolint:gocritic // in-memory provisioners are owned by system
14951500
daemon, err := api.Database.UpsertProvisionerDaemon(dbauthz.AsSystemRestricted(dialCtx), database.UpsertProvisionerDaemonParams{
14961501
Name: name,
@@ -1501,6 +1506,7 @@ func (api *API) CreateInMemoryTaggedProvisionerDaemon(dialCtx context.Context, n
15011506
LastSeenAt: sql.NullTime{Time: dbtime.Now(), Valid: true},
15021507
Version: buildinfo.Version(),
15031508
APIVersion: proto.CurrentVersion.String(),
1509+
KeyID: keyID,
15041510
})
15051511
if err != nil {
15061512
return nil, xerrors.Errorf("failed to create in-memory provisioner daemon: %w", err)

coderd/database/db2sdk/db2sdk.go

+25
Original file line numberDiff line numberDiff line change
@@ -533,13 +533,38 @@ func ProvisionerDaemon(dbDaemon database.ProvisionerDaemon) codersdk.Provisioner
533533
Tags: dbDaemon.Tags,
534534
Version: dbDaemon.Version,
535535
APIVersion: dbDaemon.APIVersion,
536+
KeyID: dbDaemon.KeyID,
536537
}
537538
for _, provisionerType := range dbDaemon.Provisioners {
538539
result.Provisioners = append(result.Provisioners, codersdk.ProvisionerType(provisionerType))
539540
}
540541
return result
541542
}
542543

544+
func RecentProvisionerDaemons(now time.Time, staleInterval time.Duration, daemons []database.ProvisionerDaemon) []codersdk.ProvisionerDaemon {
545+
results := []codersdk.ProvisionerDaemon{}
546+
547+
for _, daemon := range daemons {
548+
// Daemon never connected, skip.
549+
if !daemon.LastSeenAt.Valid {
550+
continue
551+
}
552+
// Daemon has gone away, skip.
553+
if now.Sub(daemon.LastSeenAt.Time) > staleInterval {
554+
continue
555+
}
556+
557+
results = append(results, ProvisionerDaemon(daemon))
558+
}
559+
560+
// Ensure stable order for display and for tests
561+
sort.Slice(results, func(i, j int) bool {
562+
return results[i].Name < results[j].Name
563+
})
564+
565+
return results
566+
}
567+
543568
func SlimRole(role rbac.Role) codersdk.SlimRole {
544569
orgID := ""
545570
if role.Identifier.OrganizationID != uuid.Nil {

coderd/database/dbauthz/dbauthz.go

+4
Original file line numberDiff line numberDiff line change
@@ -3066,6 +3066,10 @@ func (q *querier) ListProvisionerKeysByOrganization(ctx context.Context, organiz
30663066
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.ListProvisionerKeysByOrganization)(ctx, organizationID)
30673067
}
30683068

3069+
func (q *querier) ListProvisionerKeysByOrganizationExcludeReserved(ctx context.Context, organizationID uuid.UUID) ([]database.ProvisionerKey, error) {
3070+
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.ListProvisionerKeysByOrganizationExcludeReserved)(ctx, organizationID)
3071+
}
3072+
30693073
func (q *querier) ListWorkspaceAgentPortShares(ctx context.Context, workspaceID uuid.UUID) ([]database.WorkspaceAgentPortShare, error) {
30703074
workspace, err := q.db.GetWorkspaceByID(ctx, workspaceID)
30713075
if err != nil {

coderd/database/dbauthz/dbauthz_test.go

+13
Original file line numberDiff line numberDiff line change
@@ -2020,6 +2020,19 @@ func (s *MethodTestSuite) TestProvisionerKeys() {
20202020
}
20212021
check.Args(org.ID).Asserts(pk, policy.ActionRead).Returns(pks)
20222022
}))
2023+
s.Run("ListProvisionerKeysByOrganizationExcludeReserved", s.Subtest(func(db database.Store, check *expects) {
2024+
org := dbgen.Organization(s.T(), db, database.Organization{})
2025+
pk := dbgen.ProvisionerKey(s.T(), db, database.ProvisionerKey{OrganizationID: org.ID})
2026+
pks := []database.ProvisionerKey{
2027+
{
2028+
ID: pk.ID,
2029+
CreatedAt: pk.CreatedAt,
2030+
OrganizationID: pk.OrganizationID,
2031+
Name: pk.Name,
2032+
},
2033+
}
2034+
check.Args(org.ID).Asserts(pk, policy.ActionRead).Returns(pks)
2035+
}))
20232036
s.Run("DeleteProvisionerKey", s.Subtest(func(db database.Store, check *expects) {
20242037
org := dbgen.Organization(s.T(), db, database.Organization{})
20252038
pk := dbgen.ProvisionerKey(s.T(), db, database.ProvisionerKey{OrganizationID: org.ID})

coderd/database/dbmem/dbmem.go

+56
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func New() database.Store {
6868
notificationPreferences: make([]database.NotificationPreference, 0),
6969
parameterSchemas: make([]database.ParameterSchema, 0),
7070
provisionerDaemons: make([]database.ProvisionerDaemon, 0),
71+
provisionerKeys: make([]database.ProvisionerKey, 0),
7172
workspaceAgents: make([]database.WorkspaceAgent, 0),
7273
provisionerJobLogs: make([]database.ProvisionerJobLog, 0),
7374
workspaceResources: make([]database.WorkspaceResource, 0),
@@ -108,6 +109,41 @@ func New() database.Store {
108109

109110
q.defaultProxyDisplayName = "Default"
110111
q.defaultProxyIconURL = "/emojis/1f3e1.png"
112+
113+
_, err = q.InsertProvisionerKey(context.Background(), database.InsertProvisionerKeyParams{
114+
ID: uuid.MustParse(codersdk.ProvisionerKeyIDBuiltIn),
115+
OrganizationID: defaultOrg.ID,
116+
CreatedAt: dbtime.Now(),
117+
HashedSecret: []byte{},
118+
Name: codersdk.ProvisionerKeyNameBuiltIn,
119+
Tags: map[string]string{},
120+
})
121+
if err != nil {
122+
panic(xerrors.Errorf("failed to create built-in provisioner key: %w", err))
123+
}
124+
_, err = q.InsertProvisionerKey(context.Background(), database.InsertProvisionerKeyParams{
125+
ID: uuid.MustParse(codersdk.ProvisionerKeyIDUserAuth),
126+
OrganizationID: defaultOrg.ID,
127+
CreatedAt: dbtime.Now(),
128+
HashedSecret: []byte{},
129+
Name: codersdk.ProvisionerKeyNameUserAuth,
130+
Tags: map[string]string{},
131+
})
132+
if err != nil {
133+
panic(xerrors.Errorf("failed to create user-auth provisioner key: %w", err))
134+
}
135+
_, err = q.InsertProvisionerKey(context.Background(), database.InsertProvisionerKeyParams{
136+
ID: uuid.MustParse(codersdk.ProvisionerKeyIDPSK),
137+
OrganizationID: defaultOrg.ID,
138+
CreatedAt: dbtime.Now(),
139+
HashedSecret: []byte{},
140+
Name: codersdk.ProvisionerKeyNamePSK,
141+
Tags: map[string]string{},
142+
})
143+
if err != nil {
144+
panic(xerrors.Errorf("failed to create psk provisioner key: %w", err))
145+
}
146+
111147
return q
112148
}
113149

@@ -7582,6 +7618,25 @@ func (q *FakeQuerier) ListProvisionerKeysByOrganization(_ context.Context, organ
75827618
return keys, nil
75837619
}
75847620

7621+
func (q *FakeQuerier) ListProvisionerKeysByOrganizationExcludeReserved(_ context.Context, organizationID uuid.UUID) ([]database.ProvisionerKey, error) {
7622+
q.mutex.RLock()
7623+
defer q.mutex.RUnlock()
7624+
7625+
keys := make([]database.ProvisionerKey, 0)
7626+
for _, key := range q.provisionerKeys {
7627+
if key.ID.String() == codersdk.ProvisionerKeyIDBuiltIn ||
7628+
key.ID.String() == codersdk.ProvisionerKeyIDUserAuth ||
7629+
key.ID.String() == codersdk.ProvisionerKeyIDPSK {
7630+
continue
7631+
}
7632+
if key.OrganizationID == organizationID {
7633+
keys = append(keys, key)
7634+
}
7635+
}
7636+
7637+
return keys, nil
7638+
}
7639+
75857640
func (q *FakeQuerier) ListWorkspaceAgentPortShares(_ context.Context, workspaceID uuid.UUID) ([]database.WorkspaceAgentPortShare, error) {
75867641
q.mutex.Lock()
75877642
defer q.mutex.Unlock()
@@ -9311,6 +9366,7 @@ func (q *FakeQuerier) UpsertProvisionerDaemon(_ context.Context, arg database.Up
93119366
Version: arg.Version,
93129367
APIVersion: arg.APIVersion,
93139368
OrganizationID: arg.OrganizationID,
9369+
KeyID: arg.KeyID,
93149370
}
93159371
q.provisionerDaemons = append(q.provisionerDaemons, d)
93169372
return d, nil

coderd/database/dbmetrics/dbmetrics.go

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbmock/dbmock.go

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbpurge/dbpurge_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/coder/coder/v2/coderd/database/dbrollup"
2727
"github.com/coder/coder/v2/coderd/database/dbtestutil"
2828
"github.com/coder/coder/v2/coderd/database/dbtime"
29+
"github.com/coder/coder/v2/codersdk"
2930
"github.com/coder/coder/v2/provisionerd/proto"
3031
"github.com/coder/coder/v2/provisionersdk"
3132
"github.com/coder/coder/v2/testutil"
@@ -412,6 +413,7 @@ func TestDeleteOldProvisionerDaemons(t *testing.T) {
412413
Version: "1.0.0",
413414
APIVersion: proto.CurrentVersion.String(),
414415
OrganizationID: defaultOrg.ID,
416+
KeyID: uuid.MustParse(codersdk.ProvisionerKeyIDBuiltIn),
415417
})
416418
require.NoError(t, err)
417419
_, err = db.UpsertProvisionerDaemon(ctx, database.UpsertProvisionerDaemonParams{
@@ -424,6 +426,7 @@ func TestDeleteOldProvisionerDaemons(t *testing.T) {
424426
Version: "1.0.0",
425427
APIVersion: proto.CurrentVersion.String(),
426428
OrganizationID: defaultOrg.ID,
429+
KeyID: uuid.MustParse(codersdk.ProvisionerKeyIDBuiltIn),
427430
})
428431
require.NoError(t, err)
429432
_, err = db.UpsertProvisionerDaemon(ctx, database.UpsertProvisionerDaemonParams{
@@ -438,6 +441,7 @@ func TestDeleteOldProvisionerDaemons(t *testing.T) {
438441
Version: "1.0.0",
439442
APIVersion: proto.CurrentVersion.String(),
440443
OrganizationID: defaultOrg.ID,
444+
KeyID: uuid.MustParse(codersdk.ProvisionerKeyIDBuiltIn),
441445
})
442446
require.NoError(t, err)
443447
_, err = db.UpsertProvisionerDaemon(ctx, database.UpsertProvisionerDaemonParams{
@@ -453,6 +457,7 @@ func TestDeleteOldProvisionerDaemons(t *testing.T) {
453457
Version: "1.0.0",
454458
APIVersion: proto.CurrentVersion.String(),
455459
OrganizationID: defaultOrg.ID,
460+
KeyID: uuid.MustParse(codersdk.ProvisionerKeyIDBuiltIn),
456461
})
457462
require.NoError(t, err)
458463

0 commit comments

Comments
 (0)