Skip to content

Commit 78ecccf

Browse files
committed
Merge branch 'main' into 40-failure-summary
2 parents aafed7c + 914f35a commit 78ecccf

File tree

107 files changed

+5320
-1672
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

107 files changed

+5320
-1672
lines changed

agent/proto/agent.pb.go

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

agent/proto/agent.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ message WorkspaceApp {
4141
UNHEALTHY = 4;
4242
}
4343
Health health = 12;
44+
bool hidden = 13;
4445
}
4546

4647
message WorkspaceAgentScript {

cli/server.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import (
5757
"cdr.dev/slog/sloggers/sloghuman"
5858
"github.com/coder/coder/v2/coderd/entitlements"
5959
"github.com/coder/coder/v2/coderd/notifications/reports"
60+
"github.com/coder/coder/v2/coderd/runtimeconfig"
6061
"github.com/coder/pretty"
6162
"github.com/coder/quartz"
6263
"github.com/coder/retry"
@@ -821,6 +822,8 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
821822
return err
822823
}
823824

825+
options.RuntimeConfig = runtimeconfig.NewManager()
826+
824827
// This should be output before the logs start streaming.
825828
cliui.Infof(inv.Stdout, "\n==> Logs will stream in below (press ctrl+c to gracefully exit):")
826829

coderd/agentapi/manifest.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,5 +229,6 @@ func dbAppToProto(dbApp database.WorkspaceApp, agent database.WorkspaceAgent, ow
229229
Threshold: dbApp.HealthcheckThreshold,
230230
},
231231
Health: agentproto.WorkspaceApp_Health(healthRaw),
232+
Hidden: dbApp.Hidden,
232233
}, nil
233234
}

coderd/agentapi/manifest_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ func TestGetManifest(t *testing.T) {
8787
Subdomain: false,
8888
SharingLevel: database.AppSharingLevelPublic,
8989
Health: database.WorkspaceAppHealthDisabled,
90+
Hidden: false,
9091
},
9192
{
9293
ID: uuid.New(),
@@ -102,6 +103,7 @@ func TestGetManifest(t *testing.T) {
102103
HealthcheckUrl: "http://localhost:4321/health",
103104
HealthcheckInterval: 20,
104105
HealthcheckThreshold: 5,
106+
Hidden: true,
105107
},
106108
}
107109
scripts = []database.WorkspaceAgentScript{
@@ -182,6 +184,7 @@ func TestGetManifest(t *testing.T) {
182184
Threshold: apps[0].HealthcheckThreshold,
183185
},
184186
Health: agentproto.WorkspaceApp_HEALTHY,
187+
Hidden: false,
185188
},
186189
{
187190
Id: apps[1].ID[:],
@@ -200,6 +203,7 @@ func TestGetManifest(t *testing.T) {
200203
Threshold: 0,
201204
},
202205
Health: agentproto.WorkspaceApp_DISABLED,
206+
Hidden: false,
203207
},
204208
{
205209
Id: apps[2].ID[:],
@@ -218,6 +222,7 @@ func TestGetManifest(t *testing.T) {
218222
Threshold: apps[2].HealthcheckThreshold,
219223
},
220224
Health: agentproto.WorkspaceApp_UNHEALTHY,
225+
Hidden: true,
221226
},
222227
}
223228
protoScripts = []*agentproto.WorkspaceAgentScript{

coderd/apidoc/docs.go

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

coderd/apidoc/swagger.json

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

coderd/coderd.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
"cdr.dev/slog"
4040
"github.com/coder/coder/v2/coderd/entitlements"
4141
"github.com/coder/coder/v2/coderd/idpsync"
42+
"github.com/coder/coder/v2/coderd/runtimeconfig"
4243
"github.com/coder/quartz"
4344
"github.com/coder/serpent"
4445

@@ -135,6 +136,7 @@ type Options struct {
135136
Logger slog.Logger
136137
Database database.Store
137138
Pubsub pubsub.Pubsub
139+
RuntimeConfig *runtimeconfig.Manager
138140

139141
// CacheDir is used for caching files served by the API.
140142
CacheDir string

coderd/coderdtest/coderdtest.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import (
6767
"github.com/coder/coder/v2/coderd/notifications"
6868
"github.com/coder/coder/v2/coderd/rbac"
6969
"github.com/coder/coder/v2/coderd/rbac/policy"
70+
"github.com/coder/coder/v2/coderd/runtimeconfig"
7071
"github.com/coder/coder/v2/coderd/schedule"
7172
"github.com/coder/coder/v2/coderd/telemetry"
7273
"github.com/coder/coder/v2/coderd/unhanger"
@@ -254,6 +255,7 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
254255
var acs dbauthz.AccessControlStore = dbauthz.AGPLTemplateAccessControlStore{}
255256
accessControlStore.Store(&acs)
256257

258+
runtimeManager := runtimeconfig.NewManager()
257259
options.Database = dbauthz.New(options.Database, options.Authorizer, *options.Logger, accessControlStore)
258260

259261
// Some routes expect a deployment ID, so just make sure one exists.
@@ -482,6 +484,7 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
482484
AppHostnameRegex: appHostnameRegex,
483485
Logger: *options.Logger,
484486
CacheDir: t.TempDir(),
487+
RuntimeConfig: runtimeManager,
485488
Database: options.Database,
486489
Pubsub: options.Pubsub,
487490
ExternalAuthConfigs: options.ExternalAuthConfigs,
@@ -1140,7 +1143,7 @@ func MustWorkspace(t testing.TB, client *codersdk.Client, workspaceID uuid.UUID)
11401143

11411144
// RequestExternalAuthCallback makes a request with the proper OAuth2 state cookie
11421145
// to the external auth callback endpoint.
1143-
func RequestExternalAuthCallback(t testing.TB, providerID string, client *codersdk.Client) *http.Response {
1146+
func RequestExternalAuthCallback(t testing.TB, providerID string, client *codersdk.Client, opts ...func(*http.Request)) *http.Response {
11441147
client.HTTPClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
11451148
return http.ErrUseLastResponse
11461149
}
@@ -1157,6 +1160,9 @@ func RequestExternalAuthCallback(t testing.TB, providerID string, client *coders
11571160
Name: codersdk.SessionTokenCookie,
11581161
Value: client.SessionToken(),
11591162
})
1163+
for _, opt := range opts {
1164+
opt(req)
1165+
}
11601166
res, err := client.HTTPClient.Do(req)
11611167
require.NoError(t, err)
11621168
t.Cleanup(func() {

coderd/coderdtest/oidctest/idp.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,6 @@ func (f *FakeIDP) AttemptLogin(t testing.TB, client *codersdk.Client, idTokenCla
479479
// This is a niche case, but it is needed for testing ConvertLoginType.
480480
func (f *FakeIDP) LoginWithClient(t testing.TB, client *codersdk.Client, idTokenClaims jwt.MapClaims, opts ...func(r *http.Request)) (*codersdk.Client, *http.Response) {
481481
t.Helper()
482-
483482
path := "/api/v2/users/oidc/callback"
484483
if f.callbackPath != "" {
485484
path = f.callbackPath
@@ -489,13 +488,23 @@ func (f *FakeIDP) LoginWithClient(t testing.TB, client *codersdk.Client, idToken
489488
f.SetRedirect(t, coderOauthURL.String())
490489

491490
cli := f.HTTPClient(client.HTTPClient)
492-
cli.CheckRedirect = func(req *http.Request, via []*http.Request) error {
491+
redirectFn := cli.CheckRedirect
492+
checkRedirect := func(req *http.Request, via []*http.Request) error {
493493
// Store the idTokenClaims to the specific state request. This ties
494494
// the claims 1:1 with a given authentication flow.
495-
state := req.URL.Query().Get("state")
496-
f.stateToIDTokenClaims.Store(state, idTokenClaims)
495+
if state := req.URL.Query().Get("state"); state != "" {
496+
f.stateToIDTokenClaims.Store(state, idTokenClaims)
497+
return nil
498+
}
499+
// This is mainly intended to prevent the _last_ redirect
500+
// The one involving the state param is a core part of the
501+
// OIDC flow and shouldn't be redirected.
502+
if redirectFn != nil {
503+
return redirectFn(req, via)
504+
}
497505
return nil
498506
}
507+
cli.CheckRedirect = checkRedirect
499508

500509
req, err := http.NewRequestWithContext(context.Background(), "GET", coderOauthURL.String(), nil)
501510
require.NoError(t, err)

coderd/database/db2sdk/db2sdk.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ func Apps(dbApps []database.WorkspaceApp, agent database.WorkspaceAgent, ownerNa
517517
Threshold: dbApp.HealthcheckThreshold,
518518
},
519519
Health: codersdk.WorkspaceAppHealth(dbApp.Health),
520+
Hidden: dbApp.Hidden,
520521
})
521522
}
522523
return apps

coderd/database/dbauthz/dbauthz.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,13 @@ func (q *querier) DeleteReplicasUpdatedBefore(ctx context.Context, updatedAt tim
11871187
return q.db.DeleteReplicasUpdatedBefore(ctx, updatedAt)
11881188
}
11891189

1190+
func (q *querier) DeleteRuntimeConfig(ctx context.Context, key string) error {
1191+
if err := q.authorizeContext(ctx, policy.ActionDelete, rbac.ResourceSystem); err != nil {
1192+
return err
1193+
}
1194+
return q.db.DeleteRuntimeConfig(ctx, key)
1195+
}
1196+
11901197
func (q *querier) DeleteTailnetAgent(ctx context.Context, arg database.DeleteTailnetAgentParams) (database.DeleteTailnetAgentRow, error) {
11911198
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceTailnetCoordinator); err != nil {
11921199
return database.DeleteTailnetAgentRow{}, err
@@ -1864,8 +1871,16 @@ func (q *querier) GetReplicasUpdatedAfter(ctx context.Context, updatedAt time.Ti
18641871
return q.db.GetReplicasUpdatedAfter(ctx, updatedAt)
18651872
}
18661873

1874+
<<<<<<< HEAD
18671875
func (q *querier) GetReportGeneratorLogByUserAndTemplate(ctx context.Context, arg database.GetReportGeneratorLogByUserAndTemplateParams) (database.ReportGeneratorLog, error) {
18681876
panic("not implemented")
1877+
=======
1878+
func (q *querier) GetRuntimeConfig(ctx context.Context, key string) (string, error) {
1879+
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil {
1880+
return "", err
1881+
}
1882+
return q.db.GetRuntimeConfig(ctx, key)
1883+
>>>>>>> main
18691884
}
18701885

18711886
func (q *querier) GetTailnetAgents(ctx context.Context, id uuid.UUID) ([]database.TailnetAgent, error) {
@@ -3922,8 +3937,16 @@ func (q *querier) UpsertProvisionerDaemon(ctx context.Context, arg database.Upse
39223937
return q.db.UpsertProvisionerDaemon(ctx, arg)
39233938
}
39243939

3940+
<<<<<<< HEAD
39253941
func (q *querier) UpsertReportGeneratorLog(ctx context.Context, arg database.UpsertReportGeneratorLogParams) error {
39263942
panic("not implemented")
3943+
=======
3944+
func (q *querier) UpsertRuntimeConfig(ctx context.Context, arg database.UpsertRuntimeConfigParams) error {
3945+
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil {
3946+
return err
3947+
}
3948+
return q.db.UpsertRuntimeConfig(ctx, arg)
3949+
>>>>>>> main
39273950
}
39283951

39293952
func (q *querier) UpsertTailnetAgent(ctx context.Context, arg database.UpsertTailnetAgentParams) (database.TailnetAgent, error) {

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2696,6 +2696,22 @@ func (s *MethodTestSuite) TestSystemFunctions() {
26962696
AgentID: uuid.New(),
26972697
}).Asserts(tpl, policy.ActionCreate)
26982698
}))
2699+
s.Run("DeleteRuntimeConfig", s.Subtest(func(db database.Store, check *expects) {
2700+
check.Args("test").Asserts(rbac.ResourceSystem, policy.ActionDelete)
2701+
}))
2702+
s.Run("GetRuntimeConfig", s.Subtest(func(db database.Store, check *expects) {
2703+
_ = db.UpsertRuntimeConfig(context.Background(), database.UpsertRuntimeConfigParams{
2704+
Key: "test",
2705+
Value: "value",
2706+
})
2707+
check.Args("test").Asserts(rbac.ResourceSystem, policy.ActionRead)
2708+
}))
2709+
s.Run("UpsertRuntimeConfig", s.Subtest(func(db database.Store, check *expects) {
2710+
check.Args(database.UpsertRuntimeConfigParams{
2711+
Key: "test",
2712+
Value: "value",
2713+
}).Asserts(rbac.ResourceSystem, policy.ActionCreate)
2714+
}))
26992715
}
27002716

27012717
func (s *MethodTestSuite) TestNotifications() {

coderd/database/dbgen/dbgen.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ func WorkspaceApp(t testing.TB, db database.Store, orig database.WorkspaceApp) d
547547
HealthcheckThreshold: takeFirst(orig.HealthcheckThreshold, 60),
548548
Health: takeFirst(orig.Health, database.WorkspaceAppHealthHealthy),
549549
DisplayOrder: takeFirst(orig.DisplayOrder, 1),
550+
Hidden: orig.Hidden,
550551
})
551552
require.NoError(t, err, "insert app")
552553
return resource

coderd/database/dbmem/dbmem.go

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ func New() database.Store {
8484
workspaceProxies: make([]database.WorkspaceProxy, 0),
8585
customRoles: make([]database.CustomRole, 0),
8686
locks: map[int64]struct{}{},
87+
runtimeConfig: map[string]string{},
8788
},
8889
}
8990
// Always start with a default org. Matching migration 198.
@@ -194,6 +195,7 @@ type data struct {
194195
workspaces []database.Workspace
195196
workspaceProxies []database.WorkspaceProxy
196197
customRoles []database.CustomRole
198+
runtimeConfig map[string]string
197199
// Locks is a map of lock names. Any keys within the map are currently
198200
// locked.
199201
locks map[int64]struct{}
@@ -1932,6 +1934,14 @@ func (q *FakeQuerier) DeleteReplicasUpdatedBefore(_ context.Context, before time
19321934
return nil
19331935
}
19341936

1937+
func (q *FakeQuerier) DeleteRuntimeConfig(_ context.Context, key string) error {
1938+
q.mutex.Lock()
1939+
defer q.mutex.Unlock()
1940+
1941+
delete(q.runtimeConfig, key)
1942+
return nil
1943+
}
1944+
19351945
func (*FakeQuerier) DeleteTailnetAgent(context.Context, database.DeleteTailnetAgentParams) (database.DeleteTailnetAgentRow, error) {
19361946
return database.DeleteTailnetAgentRow{}, ErrUnimplemented
19371947
}
@@ -2666,14 +2676,14 @@ func (q *FakeQuerier) GetGroupMembersByGroupID(ctx context.Context, id uuid.UUID
26662676

26672677
var groupMembers []database.GroupMember
26682678
for _, member := range q.groupMembers {
2669-
groupMember, err := q.getGroupMemberNoLock(ctx, member.UserID, member.GroupID)
2670-
if errors.Is(err, errUserDeleted) {
2671-
continue
2672-
}
2673-
if err != nil {
2674-
return nil, err
2675-
}
26762679
if member.GroupID == id {
2680+
groupMember, err := q.getGroupMemberNoLock(ctx, member.UserID, member.GroupID)
2681+
if errors.Is(err, errUserDeleted) {
2682+
continue
2683+
}
2684+
if err != nil {
2685+
return nil, err
2686+
}
26772687
groupMembers = append(groupMembers, groupMember)
26782688
}
26792689
}
@@ -3527,6 +3537,18 @@ func (q *FakeQuerier) GetReportGeneratorLogByUserAndTemplate(ctx context.Context
35273537
panic("not implemented")
35283538
}
35293539

3540+
func (q *FakeQuerier) GetRuntimeConfig(_ context.Context, key string) (string, error) {
3541+
q.mutex.Lock()
3542+
defer q.mutex.Unlock()
3543+
3544+
val, ok := q.runtimeConfig[key]
3545+
if !ok {
3546+
return "", sql.ErrNoRows
3547+
}
3548+
3549+
return val, nil
3550+
}
3551+
35303552
func (*FakeQuerier) GetTailnetAgents(context.Context, uuid.UUID) ([]database.TailnetAgent, error) {
35313553
return nil, ErrUnimplemented
35323554
}
@@ -7317,6 +7339,7 @@ func (q *FakeQuerier) InsertWorkspaceApp(_ context.Context, arg database.InsertW
73177339
HealthcheckInterval: arg.HealthcheckInterval,
73187340
HealthcheckThreshold: arg.HealthcheckThreshold,
73197341
Health: arg.Health,
7342+
Hidden: arg.Hidden,
73207343
DisplayOrder: arg.DisplayOrder,
73217344
}
73227345
q.workspaceApps = append(q.workspaceApps, workspaceApp)
@@ -9213,12 +9236,20 @@ func (q *FakeQuerier) UpsertProvisionerDaemon(_ context.Context, arg database.Up
92139236
}
92149237

92159238
func (q *FakeQuerier) UpsertReportGeneratorLog(ctx context.Context, arg database.UpsertReportGeneratorLogParams) error {
9239+
panic("not implemented")
9240+
}
9241+
9242+
func (q *FakeQuerier) UpsertRuntimeConfig(_ context.Context, arg database.UpsertRuntimeConfigParams) error {
92169243
err := validateDatabaseType(arg)
92179244
if err != nil {
92189245
return err
92199246
}
92209247

9221-
panic("not implemented")
9248+
q.mutex.Lock()
9249+
defer q.mutex.Unlock()
9250+
9251+
q.runtimeConfig[arg.Key] = arg.Value
9252+
return nil
92229253
}
92239254

92249255
func (*FakeQuerier) UpsertTailnetAgent(context.Context, database.UpsertTailnetAgentParams) (database.TailnetAgent, error) {

0 commit comments

Comments
 (0)