Skip to content

Commit 9a1e9eb

Browse files
authored
docs: rebase restructure-new on main (#14960)
1 parent eecaacd commit 9a1e9eb

File tree

153 files changed

+6672
-2226
lines changed

Some content is hidden

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

153 files changed

+6672
-2226
lines changed

.github/workflows/contrib.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
steps:
3737
- name: cla
3838
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
39-
uses: contributor-assistant/github-action@v2.6.0
39+
uses: contributor-assistant/github-action@v2.6.1
4040
env:
4141
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4242
# the below token should have repo scope and must be manually added by you in the repository's secret

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ gen: \
488488
agent/proto/agent.pb.go \
489489
provisionersdk/proto/provisioner.pb.go \
490490
provisionerd/proto/provisionerd.pb.go \
491+
vpn/vpn.pb.go \
491492
coderd/database/dump.sql \
492493
$(DB_GEN_FILES) \
493494
site/src/api/typesGenerated.ts \
@@ -517,6 +518,7 @@ gen/mark-fresh:
517518
agent/proto/agent.pb.go \
518519
provisionersdk/proto/provisioner.pb.go \
519520
provisionerd/proto/provisionerd.pb.go \
521+
vpn/vpn.pb.go \
520522
coderd/database/dump.sql \
521523
$(DB_GEN_FILES) \
522524
site/src/api/typesGenerated.ts \
@@ -600,6 +602,12 @@ provisionerd/proto/provisionerd.pb.go: provisionerd/proto/provisionerd.proto
600602
--go-drpc_opt=paths=source_relative \
601603
./provisionerd/proto/provisionerd.proto
602604

605+
vpn/vpn.pb.go: vpn/vpn.proto
606+
protoc \
607+
--go_out=. \
608+
--go_opt=paths=source_relative \
609+
./vpn/vpn.proto
610+
603611
site/src/api/typesGenerated.ts: $(wildcard scripts/apitypings/*) $(shell find ./codersdk $(FIND_EXCLUSIONS) -type f -name '*.go')
604612
go run ./scripts/apitypings/ > $@
605613
./scripts/pnpm_install.sh

buildinfo/buildinfo.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ var (
2424
// Updated by buildinfo_slim.go on start.
2525
slim bool
2626

27+
// Updated by buildinfo_site.go on start.
28+
site bool
29+
2730
// Injected with ldflags at build, see scripts/build_go.sh
2831
tag string
2932
agpl string // either "true" or "false", ldflags does not support bools
@@ -95,6 +98,11 @@ func IsSlim() bool {
9598
return slim
9699
}
97100

101+
// HasSite returns true if the frontend is embedded in the build.
102+
func HasSite() bool {
103+
return site
104+
}
105+
98106
// IsAGPL returns true if this is an AGPL build.
99107
func IsAGPL() bool {
100108
return strings.Contains(agpl, "t")

buildinfo/buildinfo_site.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//go:build embed
2+
3+
package buildinfo
4+
5+
func init() {
6+
site = true
7+
}

cli/notifications_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ func createOpts(t *testing.T) *coderdtest.Options {
2020
t.Helper()
2121

2222
dt := coderdtest.DeploymentValues(t)
23-
dt.Experiments = []string{string(codersdk.ExperimentNotifications)}
2423
return &coderdtest.Options{
2524
DeploymentValues: dt,
2625
}

cli/root.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ func (r *RootCmd) Command(subcommands []*serpent.Command) (*serpent.Command, err
411411
{
412412
Flag: varNoOpen,
413413
Env: "CODER_NO_OPEN",
414-
Description: "Suppress opening the browser after logging in.",
414+
Description: "Suppress opening the browser when logging in, or starting the server.",
415415
Value: serpent.BoolOf(&r.noOpen),
416416
Hidden: true,
417417
Group: globalGroup,

cli/server.go

Lines changed: 48 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,16 @@ import (
5656

5757
"cdr.dev/slog"
5858
"cdr.dev/slog/sloggers/sloghuman"
59-
"github.com/coder/coder/v2/coderd/entitlements"
60-
"github.com/coder/coder/v2/coderd/notifications/reports"
61-
"github.com/coder/coder/v2/coderd/runtimeconfig"
6259
"github.com/coder/pretty"
6360
"github.com/coder/quartz"
6461
"github.com/coder/retry"
6562
"github.com/coder/serpent"
6663
"github.com/coder/wgtunnel/tunnelsdk"
6764

65+
"github.com/coder/coder/v2/coderd/entitlements"
66+
"github.com/coder/coder/v2/coderd/notifications/reports"
67+
"github.com/coder/coder/v2/coderd/runtimeconfig"
68+
6869
"github.com/coder/coder/v2/buildinfo"
6970
"github.com/coder/coder/v2/cli/clilog"
7071
"github.com/coder/coder/v2/cli/cliui"
@@ -492,7 +493,12 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
492493
BorderForeground(lipgloss.Color("12")).
493494
Render(fmt.Sprintf("View the Web UI:\n%s",
494495
pretty.Sprint(cliui.DefaultStyles.Hyperlink, accessURL))))
495-
_ = openURL(inv, accessURL)
496+
if buildinfo.HasSite() {
497+
err = openURL(inv, accessURL)
498+
if err == nil {
499+
cliui.Infof(inv.Stdout, "Opening local browser... You can disable this by passing --no-open.\n")
500+
}
501+
}
496502

497503
// Used for zero-trust instance identity with Google Cloud.
498504
googleTokenValidator, err := idtoken.NewValidator(ctx, option.WithoutAuthentication())
@@ -679,10 +685,6 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
679685
options.OIDCConfig = oc
680686
}
681687

682-
experiments := coderd.ReadExperiments(
683-
options.Logger, options.DeploymentValues.Experiments.Value(),
684-
)
685-
686688
// We'll read from this channel in the select below that tracks shutdown. If it remains
687689
// nil, that case of the select will just never fire, but it's important not to have a
688690
// "bare" read on this channel.
@@ -946,6 +948,33 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
946948
return xerrors.Errorf("write config url: %w", err)
947949
}
948950

951+
// Manage notifications.
952+
cfg := options.DeploymentValues.Notifications
953+
metrics := notifications.NewMetrics(options.PrometheusRegistry)
954+
helpers := templateHelpers(options)
955+
956+
// The enqueuer is responsible for enqueueing notifications to the given store.
957+
enqueuer, err := notifications.NewStoreEnqueuer(cfg, options.Database, helpers, logger.Named("notifications.enqueuer"), quartz.NewReal())
958+
if err != nil {
959+
return xerrors.Errorf("failed to instantiate notification store enqueuer: %w", err)
960+
}
961+
options.NotificationsEnqueuer = enqueuer
962+
963+
// The notification manager is responsible for:
964+
// - creating notifiers and managing their lifecycles (notifiers are responsible for dequeueing/sending notifications)
965+
// - keeping the store updated with status updates
966+
notificationsManager, err := notifications.NewManager(cfg, options.Database, helpers, metrics, logger.Named("notifications.manager"))
967+
if err != nil {
968+
return xerrors.Errorf("failed to instantiate notification manager: %w", err)
969+
}
970+
971+
// nolint:gocritic // TODO: create own role.
972+
notificationsManager.Run(dbauthz.AsSystemRestricted(ctx))
973+
974+
// Run report generator to distribute periodic reports.
975+
notificationReportGenerator := reports.NewReportGenerator(ctx, logger.Named("notifications.report_generator"), options.Database, options.NotificationsEnqueuer, quartz.NewReal())
976+
defer notificationReportGenerator.Close()
977+
949978
// Since errCh only has one buffered slot, all routines
950979
// sending on it must be wrapped in a select/default to
951980
// avoid leaving dangling goroutines waiting for the
@@ -1002,38 +1031,6 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
10021031
options.WorkspaceUsageTracker = tracker
10031032
defer tracker.Close()
10041033

1005-
// Manage notifications.
1006-
var (
1007-
notificationsManager *notifications.Manager
1008-
)
1009-
if experiments.Enabled(codersdk.ExperimentNotifications) {
1010-
cfg := options.DeploymentValues.Notifications
1011-
metrics := notifications.NewMetrics(options.PrometheusRegistry)
1012-
helpers := templateHelpers(options)
1013-
1014-
// The enqueuer is responsible for enqueueing notifications to the given store.
1015-
enqueuer, err := notifications.NewStoreEnqueuer(cfg, options.Database, helpers, logger.Named("notifications.enqueuer"), quartz.NewReal())
1016-
if err != nil {
1017-
return xerrors.Errorf("failed to instantiate notification store enqueuer: %w", err)
1018-
}
1019-
options.NotificationsEnqueuer = enqueuer
1020-
1021-
// The notification manager is responsible for:
1022-
// - creating notifiers and managing their lifecycles (notifiers are responsible for dequeueing/sending notifications)
1023-
// - keeping the store updated with status updates
1024-
notificationsManager, err = notifications.NewManager(cfg, options.Database, helpers, metrics, logger.Named("notifications.manager"))
1025-
if err != nil {
1026-
return xerrors.Errorf("failed to instantiate notification manager: %w", err)
1027-
}
1028-
1029-
// nolint:gocritic // TODO: create own role.
1030-
notificationsManager.Run(dbauthz.AsSystemRestricted(ctx))
1031-
1032-
// Run report generator to distribute periodic reports.
1033-
notificationReportGenerator := reports.NewReportGenerator(ctx, logger.Named("notifications.report_generator"), options.Database, options.NotificationsEnqueuer, quartz.NewReal())
1034-
defer notificationReportGenerator.Close()
1035-
}
1036-
10371034
// Wrap the server in middleware that redirects to the access URL if
10381035
// the request is not to a local IP.
10391036
var handler http.Handler = coderAPI.RootHandler
@@ -1153,19 +1150,17 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
11531150
// Cancel any remaining in-flight requests.
11541151
shutdownConns()
11551152

1156-
if notificationsManager != nil {
1157-
// Stop the notification manager, which will cause any buffered updates to the store to be flushed.
1158-
// If the Stop() call times out, messages that were sent but not reflected as such in the store will have
1159-
// their leases expire after a period of time and will be re-queued for sending.
1160-
// See CODER_NOTIFICATIONS_LEASE_PERIOD.
1161-
cliui.Info(inv.Stdout, "Shutting down notifications manager..."+"\n")
1162-
err = shutdownWithTimeout(notificationsManager.Stop, 5*time.Second)
1163-
if err != nil {
1164-
cliui.Warnf(inv.Stderr, "Notifications manager shutdown took longer than 5s, "+
1165-
"this may result in duplicate notifications being sent: %s\n", err)
1166-
} else {
1167-
cliui.Info(inv.Stdout, "Gracefully shut down notifications manager\n")
1168-
}
1153+
// Stop the notification manager, which will cause any buffered updates to the store to be flushed.
1154+
// If the Stop() call times out, messages that were sent but not reflected as such in the store will have
1155+
// their leases expire after a period of time and will be re-queued for sending.
1156+
// See CODER_NOTIFICATIONS_LEASE_PERIOD.
1157+
cliui.Info(inv.Stdout, "Shutting down notifications manager..."+"\n")
1158+
err = shutdownWithTimeout(notificationsManager.Stop, 5*time.Second)
1159+
if err != nil {
1160+
cliui.Warnf(inv.Stderr, "Notifications manager shutdown took longer than 5s, "+
1161+
"this may result in duplicate notifications being sent: %s\n", err)
1162+
} else {
1163+
cliui.Info(inv.Stdout, "Gracefully shut down notifications manager\n")
11691164
}
11701165

11711166
// Shut down provisioners before waiting for WebSockets

cli/testdata/coder_tokens_create_--help.golden

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,9 @@ OPTIONS:
1212
-n, --name string, $CODER_TOKEN_NAME
1313
Specify a human-readable name.
1414

15+
-u, --user string, $CODER_TOKEN_USER
16+
Specify the user to create the token for (Only works if logged in user
17+
is admin).
18+
1519
———
1620
Run `coder --help` for a list of global options.

cli/tokens.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ func (r *RootCmd) createToken() *serpent.Command {
4848
var (
4949
tokenLifetime time.Duration
5050
name string
51+
user string
5152
)
5253
client := new(codersdk.Client)
5354
cmd := &serpent.Command{
@@ -58,7 +59,11 @@ func (r *RootCmd) createToken() *serpent.Command {
5859
r.InitClient(client),
5960
),
6061
Handler: func(inv *serpent.Invocation) error {
61-
res, err := client.CreateToken(inv.Context(), codersdk.Me, codersdk.CreateTokenRequest{
62+
userID := codersdk.Me
63+
if user != "" {
64+
userID = user
65+
}
66+
res, err := client.CreateToken(inv.Context(), userID, codersdk.CreateTokenRequest{
6267
Lifetime: tokenLifetime,
6368
TokenName: name,
6469
})
@@ -87,6 +92,13 @@ func (r *RootCmd) createToken() *serpent.Command {
8792
Description: "Specify a human-readable name.",
8893
Value: serpent.StringOf(&name),
8994
},
95+
{
96+
Flag: "user",
97+
FlagShorthand: "u",
98+
Env: "CODER_TOKEN_USER",
99+
Description: "Specify the user to create the token for (Only works if logged in user is admin).",
100+
Value: serpent.StringOf(&user),
101+
},
90102
}
91103

92104
return cmd

cli/tokens_test.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@ import (
1717
func TestTokens(t *testing.T) {
1818
t.Parallel()
1919
client := coderdtest.New(t, nil)
20-
_ = coderdtest.CreateFirstUser(t, client)
20+
adminUser := coderdtest.CreateFirstUser(t, client)
21+
22+
secondUserClient, secondUser := coderdtest.CreateAnotherUser(t, client, adminUser.OrganizationID)
23+
_, thirdUser := coderdtest.CreateAnotherUser(t, client, adminUser.OrganizationID)
2124

2225
ctx, cancelFunc := context.WithTimeout(context.Background(), testutil.WaitLong)
2326
defer cancelFunc()
2427

2528
// helpful empty response
2629
inv, root := clitest.New(t, "tokens", "ls")
30+
//nolint:gocritic // This should be run as the owner user.
2731
clitest.SetupConfig(t, client, root)
2832
buf := new(bytes.Buffer)
2933
inv.Stdout = buf
@@ -42,6 +46,19 @@ func TestTokens(t *testing.T) {
4246
require.NotEmpty(t, res)
4347
id := res[:10]
4448

49+
// Test creating a token for second user from first user's (admin) session
50+
inv, root = clitest.New(t, "tokens", "create", "--name", "token-two", "--user", secondUser.ID.String())
51+
clitest.SetupConfig(t, client, root)
52+
buf = new(bytes.Buffer)
53+
inv.Stdout = buf
54+
err = inv.WithContext(ctx).Run()
55+
// Test should succeed in creating token for second user
56+
require.NoError(t, err)
57+
res = buf.String()
58+
require.NotEmpty(t, res)
59+
secondTokenID := res[:10]
60+
61+
// Test listing tokens from the first user's (admin) session
4562
inv, root = clitest.New(t, "tokens", "ls")
4663
clitest.SetupConfig(t, client, root)
4764
buf = new(bytes.Buffer)
@@ -50,11 +67,39 @@ func TestTokens(t *testing.T) {
5067
require.NoError(t, err)
5168
res = buf.String()
5269
require.NotEmpty(t, res)
70+
// Result should only contain the token created for the admin user
5371
require.Contains(t, res, "ID")
5472
require.Contains(t, res, "EXPIRES AT")
5573
require.Contains(t, res, "CREATED AT")
5674
require.Contains(t, res, "LAST USED")
5775
require.Contains(t, res, id)
76+
// Result should not contain the token created for the second user
77+
require.NotContains(t, res, secondTokenID)
78+
79+
// Test listing tokens from the second user's session
80+
inv, root = clitest.New(t, "tokens", "ls")
81+
clitest.SetupConfig(t, secondUserClient, root)
82+
buf = new(bytes.Buffer)
83+
inv.Stdout = buf
84+
err = inv.WithContext(ctx).Run()
85+
require.NoError(t, err)
86+
res = buf.String()
87+
require.NotEmpty(t, res)
88+
require.Contains(t, res, "ID")
89+
require.Contains(t, res, "EXPIRES AT")
90+
require.Contains(t, res, "CREATED AT")
91+
require.Contains(t, res, "LAST USED")
92+
// Result should contain the token created for the second user
93+
require.Contains(t, res, secondTokenID)
94+
95+
// Test creating a token for third user from second user's (non-admin) session
96+
inv, root = clitest.New(t, "tokens", "create", "--name", "token-two", "--user", thirdUser.ID.String())
97+
clitest.SetupConfig(t, secondUserClient, root)
98+
buf = new(bytes.Buffer)
99+
inv.Stdout = buf
100+
err = inv.WithContext(ctx).Run()
101+
// User (non-admin) should not be able to create a token for another user
102+
require.Error(t, err)
58103

59104
inv, root = clitest.New(t, "tokens", "ls", "--output=json")
60105
clitest.SetupConfig(t, client, root)

0 commit comments

Comments
 (0)