Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc501cf9

Browse files
committed
add cli command to regenerate vapid keypair and remove existing subscriptions
1 parent800573c commitc501cf9

26 files changed

+781
-101
lines changed

‎cli/server.go‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -776,11 +776,18 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
776776
returnxerrors.Errorf("set deployment id: %w",err)
777777
}
778778

779-
pushNotifier,err:=push.New(ctx,&options.Logger,options.Database)
780-
iferr!=nil {
781-
returnxerrors.Errorf("failed to create push notifier: %w",err)
779+
// Manage push notifications.
780+
{
781+
pushNotifier,err:=push.New(ctx,&options.Logger,options.Database)
782+
iferr!=nil {
783+
options.Logger.Error(ctx,"failed to create push notifier",slog.Error(err))
784+
options.Logger.Warn(ctx,"push notifications will not work until the VAPID keys are regenerated")
785+
pushNotifier=&push.NoopNotifier{
786+
Msg:"Push notifications are disabled due to a system error. Please contact your Coder administrator.",
787+
}
788+
}
789+
options.PushNotifier=pushNotifier
782790
}
783-
options.PushNotifier=pushNotifier
784791

785792
githubOAuth2ConfigParams,err:=getGithubOAuth2ConfigParams(ctx,options.Database,vals)
786793
iferr!=nil {
@@ -1262,6 +1269,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
12621269
}
12631270

12641271
createAdminUserCmd:=r.newCreateAdminUserCommand()
1272+
regenerateVapidKeypairCmd:=r.newRegenerateVapidKeypairCommand()
12651273

12661274
rawURLOpt:= serpent.Option{
12671275
Flag:"raw-url",
@@ -1275,7 +1283,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
12751283

12761284
serverCmd.Children=append(
12771285
serverCmd.Children,
1278-
createAdminUserCmd,postgresBuiltinURLCmd,postgresBuiltinServeCmd,
1286+
createAdminUserCmd,postgresBuiltinURLCmd,postgresBuiltinServeCmd,regenerateVapidKeypairCmd,
12791287
)
12801288

12811289
returnserverCmd
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
//go:build !slim
2+
3+
package cli
4+
5+
import (
6+
"fmt"
7+
8+
"golang.org/x/xerrors"
9+
10+
"cdr.dev/slog"
11+
"cdr.dev/slog/sloggers/sloghuman"
12+
13+
"github.com/coder/coder/v2/cli/cliui"
14+
"github.com/coder/coder/v2/coderd/database"
15+
"github.com/coder/coder/v2/coderd/database/awsiamrds"
16+
"github.com/coder/coder/v2/coderd/notifications/push"
17+
"github.com/coder/coder/v2/codersdk"
18+
"github.com/coder/serpent"
19+
)
20+
21+
func (r*RootCmd)newRegenerateVapidKeypairCommand()*serpent.Command {
22+
var (
23+
regenVapidKeypairDBURLstring
24+
regenVapidKeypairPgAuthstring
25+
)
26+
regenerateVapidKeypairCommand:=&serpent.Command{
27+
Use:"regenerate-vapid-keypair",
28+
Short:"Regenerate the VAPID keypair used for push notifications.",
29+
Handler:func(inv*serpent.Invocation)error {
30+
var (
31+
ctx,cancel=inv.SignalNotifyContext(inv.Context(),StopSignals...)
32+
cfg=r.createConfig()
33+
logger=inv.Logger.AppendSinks(sloghuman.Sink(inv.Stderr))
34+
)
35+
ifr.verbose {
36+
logger=logger.Leveled(slog.LevelDebug)
37+
}
38+
39+
defercancel()
40+
41+
ifregenVapidKeypairDBURL=="" {
42+
cliui.Infof(inv.Stdout,"Using built-in PostgreSQL (%s)",cfg.PostgresPath())
43+
url,closePg,err:=startBuiltinPostgres(ctx,cfg,logger,"")
44+
iferr!=nil {
45+
returnerr
46+
}
47+
deferfunc() {
48+
_=closePg()
49+
}()
50+
regenVapidKeypairDBURL=url
51+
}
52+
53+
sqlDriver:="postgres"
54+
varerrerror
55+
ifcodersdk.PostgresAuth(regenVapidKeypairPgAuth)==codersdk.PostgresAuthAWSIAMRDS {
56+
sqlDriver,err=awsiamrds.Register(inv.Context(),sqlDriver)
57+
iferr!=nil {
58+
returnxerrors.Errorf("register aws rds iam auth: %w",err)
59+
}
60+
}
61+
62+
sqlDB,err:=ConnectToPostgres(ctx,logger,sqlDriver,regenVapidKeypairDBURL,nil)
63+
iferr!=nil {
64+
returnxerrors.Errorf("connect to postgres: %w",err)
65+
}
66+
deferfunc() {
67+
_=sqlDB.Close()
68+
}()
69+
db:=database.New(sqlDB)
70+
71+
// Confirm that the user really wants to regenerate the VAPID keypair.
72+
cliui.Infof(inv.Stdout,"Regenerating VAPID keypair...")
73+
cliui.Infof(inv.Stdout,"This will delete all existing push notification subscriptions.")
74+
cliui.Infof(inv.Stdout,"Are you sure you want to continue? (y/N)")
75+
76+
ifresp,err:=cliui.Prompt(inv, cliui.PromptOptions{
77+
IsConfirm:true,
78+
Default:cliui.ConfirmNo,
79+
});err!=nil||resp!=cliui.ConfirmYes {
80+
returnxerrors.Errorf("VAPID keypair regeneration failed: %w",err)
81+
}
82+
83+
if_,_,err:=push.RegenerateVAPIDKeys(ctx,db);err!=nil {
84+
returnxerrors.Errorf("regenerate vapid keypair: %w",err)
85+
}
86+
87+
_,_=fmt.Fprintln(inv.Stdout,"VAPID keypair regenerated successfully.")
88+
returnnil
89+
},
90+
}
91+
92+
regenerateVapidKeypairCommand.Options.Add(
93+
cliui.SkipPromptOption(),
94+
serpent.Option{
95+
Env:"CODER_PG_CONNECTION_URL",
96+
Flag:"postgres-url",
97+
Description:"URL of a PostgreSQL database. If empty, the built-in PostgreSQL deployment will be used (Coder must not be already running in this case).",
98+
Value:serpent.StringOf(&regenVapidKeypairDBURL),
99+
},
100+
serpent.Option{
101+
Name:"Postgres Connection Auth",
102+
Description:"Type of auth to use when connecting to postgres.",
103+
Flag:"postgres-connection-auth",
104+
Env:"CODER_PG_CONNECTION_AUTH",
105+
Default:"password",
106+
Value:serpent.EnumOf(&regenVapidKeypairPgAuth,codersdk.PostgresAuthDrivers...),
107+
},
108+
)
109+
110+
returnregenerateVapidKeypairCommand
111+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package cli_test
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
"testing"
7+
8+
"github.com/stretchr/testify/require"
9+
10+
"github.com/coder/coder/v2/cli/clitest"
11+
"github.com/coder/coder/v2/coderd/database"
12+
"github.com/coder/coder/v2/coderd/database/dbgen"
13+
"github.com/coder/coder/v2/coderd/database/dbtestutil"
14+
"github.com/coder/coder/v2/pty/ptytest"
15+
"github.com/coder/coder/v2/testutil"
16+
)
17+
18+
funcTestRegenerateVapidKeypair(t*testing.T) {
19+
t.Parallel()
20+
21+
t.Run("NoExistingVAPIDKeys",func(t*testing.T) {
22+
t.Parallel()
23+
24+
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitShort)
25+
t.Cleanup(cancel)
26+
27+
connectionURL,err:=dbtestutil.Open(t)
28+
require.NoError(t,err)
29+
30+
sqlDB,err:=sql.Open("postgres",connectionURL)
31+
require.NoError(t,err)
32+
defersqlDB.Close()
33+
34+
db:=database.New(sqlDB)
35+
// Ensure there is no existing VAPID keypair.
36+
rows,err:=db.GetNotificationVAPIDKeys(ctx)
37+
require.NoError(t,err)
38+
require.Empty(t,rows)
39+
40+
inv,_:=clitest.New(t,"server","regenerate-vapid-keypair","--postgres-url",connectionURL,"--yes")
41+
42+
pty:=ptytest.New(t)
43+
inv.Stdout=pty.Output()
44+
inv.Stderr=pty.Output()
45+
clitest.Start(t,inv)
46+
47+
pty.ExpectMatchContext(ctx,"Regenerating VAPID keypair...")
48+
pty.ExpectMatchContext(ctx,"This will delete all existing push notification subscriptions.")
49+
pty.ExpectMatchContext(ctx,"Are you sure you want to continue? (y/N)")
50+
pty.WriteLine("y")
51+
pty.ExpectMatchContext(ctx,"VAPID keypair regenerated successfully.")
52+
53+
// Ensure the VAPID keypair was created.
54+
keys,err:=db.GetNotificationVAPIDKeys(ctx)
55+
require.NoError(t,err)
56+
require.NotEmpty(t,keys.VapidPublicKey)
57+
require.NotEmpty(t,keys.VapidPrivateKey)
58+
})
59+
60+
t.Run("ExistingVAPIDKeys",func(t*testing.T) {
61+
t.Parallel()
62+
63+
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitShort)
64+
t.Cleanup(cancel)
65+
66+
connectionURL,err:=dbtestutil.Open(t)
67+
require.NoError(t,err)
68+
69+
sqlDB,err:=sql.Open("postgres",connectionURL)
70+
require.NoError(t,err)
71+
defersqlDB.Close()
72+
73+
db:=database.New(sqlDB)
74+
fori:=0;i<10;i++ {
75+
// Insert a few fake users.
76+
u:=dbgen.User(t,db, database.User{})
77+
// Insert a few fake push subscriptions for each user.
78+
forj:=0;j<10;j++ {
79+
_=dbgen.NotificationPushSubscription(t,db, database.InsertNotificationPushSubscriptionParams{
80+
UserID:u.ID,
81+
})
82+
}
83+
}
84+
85+
inv,_:=clitest.New(t,"server","regenerate-vapid-keypair","--postgres-url",connectionURL,"--yes")
86+
87+
pty:=ptytest.New(t)
88+
inv.Stdout=pty.Output()
89+
inv.Stderr=pty.Output()
90+
clitest.Start(t,inv)
91+
92+
pty.ExpectMatchContext(ctx,"Regenerating VAPID keypair...")
93+
pty.ExpectMatchContext(ctx,"This will delete all existing push notification subscriptions.")
94+
pty.ExpectMatchContext(ctx,"Are you sure you want to continue? (y/N)")
95+
pty.WriteLine("y")
96+
pty.ExpectMatchContext(ctx,"VAPID keypair regenerated successfully.")
97+
98+
// Ensure the VAPID keypair was created.
99+
keys,err:=db.GetNotificationVAPIDKeys(ctx)
100+
require.NoError(t,err)
101+
require.NotEmpty(t,keys.VapidPublicKey)
102+
require.NotEmpty(t,keys.VapidPrivateKey)
103+
104+
// Ensure the push subscriptions were deleted.
105+
varcountint64
106+
rows,err:=sqlDB.QueryContext(ctx,"SELECT COUNT(*) FROM notification_push_subscriptions")
107+
require.NoError(t,err)
108+
t.Cleanup(func() {
109+
_=rows.Close()
110+
})
111+
require.True(t,rows.Next())
112+
require.NoError(t,rows.Scan(&count))
113+
require.Equal(t,int64(0),count)
114+
})
115+
}

‎cli/testdata/coder_server_--help.golden‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ USAGE:
66
Start a Coder server
77

88
SUBCOMMANDS:
9-
create-admin-user Create a new admin user with the given username,
10-
email and password and adds it to every
11-
organization.
12-
postgres-builtin-serve Run the built-in PostgreSQL deployment.
13-
postgres-builtin-url Output the connection URL for the built-in
14-
PostgreSQL deployment.
9+
create-admin-user Create a new admin user with the given username,
10+
email and password and adds it to every
11+
organization.
12+
postgres-builtin-serve Run the built-in PostgreSQL deployment.
13+
postgres-builtin-url Output the connection URL for the built-in
14+
PostgreSQL deployment.
15+
regenerate-vapid-keypair Regenerate the VAPID keypair used for push
16+
notifications.
1517

1618
OPTIONS:
1719
--allow-workspace-renames bool, $CODER_ALLOW_WORKSPACE_RENAMES (default: false)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
coder v0.0.0-devel
2+
3+
USAGE:
4+
coder server regenerate-vapid-keypair [flags]
5+
6+
Regenerate the VAPID keypair used for push notifications.
7+
8+
OPTIONS:
9+
--postgres-connection-auth password|awsiamrds, $CODER_PG_CONNECTION_AUTH (default: password)
10+
Type of auth to use when connecting to postgres.
11+
12+
--postgres-url string, $CODER_PG_CONNECTION_URL
13+
URL of a PostgreSQL database. If empty, the built-in PostgreSQL
14+
deployment will be used (Coder must not be already running in this
15+
case).
16+
17+
-y, --yes bool
18+
Bypass prompts.
19+
20+
———
21+
Run `coder --help` for a list of global options.

‎coderd/apidoc/docs.go‎

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp