mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
feat(cli): pause notifications (#13873)
This commit is contained in:
85
cli/notifications.go
Normal file
85
cli/notifications.go
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/coder/serpent"
|
||||||
|
|
||||||
|
"github.com/coder/coder/v2/codersdk"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (r *RootCmd) notifications() *serpent.Command {
|
||||||
|
cmd := &serpent.Command{
|
||||||
|
Use: "notifications",
|
||||||
|
Short: "Manage Coder notifications",
|
||||||
|
Long: "Administrators can use these commands to change notification settings.\n" + FormatExamples(
|
||||||
|
Example{
|
||||||
|
Description: "Pause Coder notifications. Administrators can temporarily stop notifiers from dispatching messages in case of the target outage (for example: unavailable SMTP server or Webhook not responding).",
|
||||||
|
Command: "coder notifications pause",
|
||||||
|
},
|
||||||
|
Example{
|
||||||
|
Description: "Resume Coder notifications",
|
||||||
|
Command: "coder notifications resume",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Aliases: []string{"notification"},
|
||||||
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
return inv.Command.HelpHandler(inv)
|
||||||
|
},
|
||||||
|
Children: []*serpent.Command{
|
||||||
|
r.pauseNotifications(),
|
||||||
|
r.resumeNotifications(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RootCmd) pauseNotifications() *serpent.Command {
|
||||||
|
client := new(codersdk.Client)
|
||||||
|
cmd := &serpent.Command{
|
||||||
|
Use: "pause",
|
||||||
|
Short: "Pause notifications",
|
||||||
|
Middleware: serpent.Chain(
|
||||||
|
serpent.RequireNArgs(0),
|
||||||
|
r.InitClient(client),
|
||||||
|
),
|
||||||
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
err := client.PutNotificationsSettings(inv.Context(), codersdk.NotificationsSettings{
|
||||||
|
NotifierPaused: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("unable to pause notifications: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintln(inv.Stderr, "Notifications are now paused.")
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RootCmd) resumeNotifications() *serpent.Command {
|
||||||
|
client := new(codersdk.Client)
|
||||||
|
cmd := &serpent.Command{
|
||||||
|
Use: "resume",
|
||||||
|
Short: "Resume notifications",
|
||||||
|
Middleware: serpent.Chain(
|
||||||
|
serpent.RequireNArgs(0),
|
||||||
|
r.InitClient(client),
|
||||||
|
),
|
||||||
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
err := client.PutNotificationsSettings(inv.Context(), codersdk.NotificationsSettings{
|
||||||
|
NotifierPaused: false,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("unable to resume notifications: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = fmt.Fprintln(inv.Stderr, "Notifications are now resumed.")
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return cmd
|
||||||
|
}
|
102
cli/notifications_test.go
Normal file
102
cli/notifications_test.go
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package cli_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/coder/coder/v2/cli/clitest"
|
||||||
|
"github.com/coder/coder/v2/coderd/coderdtest"
|
||||||
|
"github.com/coder/coder/v2/codersdk"
|
||||||
|
"github.com/coder/coder/v2/testutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNotifications(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
command string
|
||||||
|
expectPaused bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "PauseNotifications",
|
||||||
|
command: "pause",
|
||||||
|
expectPaused: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ResumeNotifications",
|
||||||
|
command: "resume",
|
||||||
|
expectPaused: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
// given
|
||||||
|
ownerClient, db := coderdtest.NewWithDatabase(t, nil)
|
||||||
|
_ = coderdtest.CreateFirstUser(t, ownerClient)
|
||||||
|
|
||||||
|
// when
|
||||||
|
inv, root := clitest.New(t, "notifications", tt.command)
|
||||||
|
clitest.SetupConfig(t, ownerClient, root)
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
inv.Stdout = &buf
|
||||||
|
err := inv.Run()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// then
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
|
||||||
|
t.Cleanup(cancel)
|
||||||
|
settingsJSON, err := db.GetNotificationsSettings(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var settings codersdk.NotificationsSettings
|
||||||
|
err = json.Unmarshal([]byte(settingsJSON), &settings)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, tt.expectPaused, settings.NotifierPaused)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPauseNotifications_RegularUser(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
// given
|
||||||
|
ownerClient, db := coderdtest.NewWithDatabase(t, nil)
|
||||||
|
owner := coderdtest.CreateFirstUser(t, ownerClient)
|
||||||
|
anotherClient, _ := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID)
|
||||||
|
|
||||||
|
// when
|
||||||
|
inv, root := clitest.New(t, "notifications", "pause")
|
||||||
|
clitest.SetupConfig(t, anotherClient, root)
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
inv.Stdout = &buf
|
||||||
|
err := inv.Run()
|
||||||
|
var sdkError *codersdk.Error
|
||||||
|
require.Error(t, err)
|
||||||
|
require.ErrorAsf(t, err, &sdkError, "error should be of type *codersdk.Error")
|
||||||
|
assert.Equal(t, http.StatusForbidden, sdkError.StatusCode())
|
||||||
|
assert.Contains(t, sdkError.Message, "Insufficient permissions to update notifications settings.")
|
||||||
|
|
||||||
|
// then
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
|
||||||
|
t.Cleanup(cancel)
|
||||||
|
settingsJSON, err := db.GetNotificationsSettings(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var settings codersdk.NotificationsSettings
|
||||||
|
err = json.Unmarshal([]byte(settingsJSON), &settings)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.False(t, settings.NotifierPaused) // still running
|
||||||
|
}
|
@ -87,6 +87,8 @@ func (r *RootCmd) CoreSubcommands() []*serpent.Command {
|
|||||||
r.login(),
|
r.login(),
|
||||||
r.logout(),
|
r.logout(),
|
||||||
r.netcheck(),
|
r.netcheck(),
|
||||||
|
r.notifications(),
|
||||||
|
r.organizations(),
|
||||||
r.portForward(),
|
r.portForward(),
|
||||||
r.publickey(),
|
r.publickey(),
|
||||||
r.resetPassword(),
|
r.resetPassword(),
|
||||||
@ -95,7 +97,6 @@ func (r *RootCmd) CoreSubcommands() []*serpent.Command {
|
|||||||
r.tokens(),
|
r.tokens(),
|
||||||
r.users(),
|
r.users(),
|
||||||
r.version(defaultVersionInfo),
|
r.version(defaultVersionInfo),
|
||||||
r.organizations(),
|
|
||||||
|
|
||||||
// Workspace Commands
|
// Workspace Commands
|
||||||
r.autoupdate(),
|
r.autoupdate(),
|
||||||
@ -120,11 +121,11 @@ func (r *RootCmd) CoreSubcommands() []*serpent.Command {
|
|||||||
r.whoami(),
|
r.whoami(),
|
||||||
|
|
||||||
// Hidden
|
// Hidden
|
||||||
|
r.expCmd(),
|
||||||
r.gitssh(),
|
r.gitssh(),
|
||||||
|
r.support(),
|
||||||
r.vscodeSSH(),
|
r.vscodeSSH(),
|
||||||
r.workspaceAgent(),
|
r.workspaceAgent(),
|
||||||
r.expCmd(),
|
|
||||||
r.support(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
cli/testdata/coder_--help.golden
vendored
1
cli/testdata/coder_--help.golden
vendored
@ -27,6 +27,7 @@ SUBCOMMANDS:
|
|||||||
login Authenticate with Coder deployment
|
login Authenticate with Coder deployment
|
||||||
logout Unauthenticate your local session
|
logout Unauthenticate your local session
|
||||||
netcheck Print network debug information for DERP and STUN
|
netcheck Print network debug information for DERP and STUN
|
||||||
|
notifications Manage Coder notifications
|
||||||
open Open a workspace
|
open Open a workspace
|
||||||
ping Ping a workspace
|
ping Ping a workspace
|
||||||
port-forward Forward ports from a workspace to the local machine. For
|
port-forward Forward ports from a workspace to the local machine. For
|
||||||
|
28
cli/testdata/coder_notifications_--help.golden
vendored
Normal file
28
cli/testdata/coder_notifications_--help.golden
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
coder v0.0.0-devel
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
coder notifications
|
||||||
|
|
||||||
|
Manage Coder notifications
|
||||||
|
|
||||||
|
Aliases: notification
|
||||||
|
|
||||||
|
Administrators can use these commands to change notification settings.
|
||||||
|
- Pause Coder notifications. Administrators can temporarily stop notifiers
|
||||||
|
from
|
||||||
|
dispatching messages in case of the target outage (for example: unavailable
|
||||||
|
SMTP
|
||||||
|
server or Webhook not responding).:
|
||||||
|
|
||||||
|
$ coder notifications pause
|
||||||
|
|
||||||
|
- Resume Coder notifications:
|
||||||
|
|
||||||
|
$ coder notifications resume
|
||||||
|
|
||||||
|
SUBCOMMANDS:
|
||||||
|
pause Pause notifications
|
||||||
|
resume Resume notifications
|
||||||
|
|
||||||
|
———
|
||||||
|
Run `coder --help` for a list of global options.
|
9
cli/testdata/coder_notifications_pause_--help.golden
vendored
Normal file
9
cli/testdata/coder_notifications_pause_--help.golden
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
coder v0.0.0-devel
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
coder notifications pause
|
||||||
|
|
||||||
|
Pause notifications
|
||||||
|
|
||||||
|
———
|
||||||
|
Run `coder --help` for a list of global options.
|
9
cli/testdata/coder_notifications_resume_--help.golden
vendored
Normal file
9
cli/testdata/coder_notifications_resume_--help.golden
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
coder v0.0.0-devel
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
coder notifications resume
|
||||||
|
|
||||||
|
Resume notifications
|
||||||
|
|
||||||
|
———
|
||||||
|
Run `coder --help` for a list of global options.
|
@ -30,6 +30,7 @@ Coder — A tool for provisioning self-hosted development environments with Terr
|
|||||||
| [<code>login</code>](./cli/login.md) | Authenticate with Coder deployment |
|
| [<code>login</code>](./cli/login.md) | Authenticate with Coder deployment |
|
||||||
| [<code>logout</code>](./cli/logout.md) | Unauthenticate your local session |
|
| [<code>logout</code>](./cli/logout.md) | Unauthenticate your local session |
|
||||||
| [<code>netcheck</code>](./cli/netcheck.md) | Print network debug information for DERP and STUN |
|
| [<code>netcheck</code>](./cli/netcheck.md) | Print network debug information for DERP and STUN |
|
||||||
|
| [<code>notifications</code>](./cli/notifications.md) | Manage Coder notifications |
|
||||||
| [<code>port-forward</code>](./cli/port-forward.md) | Forward ports from a workspace to the local machine. For reverse port forwarding, use "coder ssh -R". |
|
| [<code>port-forward</code>](./cli/port-forward.md) | Forward ports from a workspace to the local machine. For reverse port forwarding, use "coder ssh -R". |
|
||||||
| [<code>publickey</code>](./cli/publickey.md) | Output your Coder public key used for Git operations |
|
| [<code>publickey</code>](./cli/publickey.md) | Output your Coder public key used for Git operations |
|
||||||
| [<code>reset-password</code>](./cli/reset-password.md) | Directly connect to the database to reset a user's password |
|
| [<code>reset-password</code>](./cli/reset-password.md) | Directly connect to the database to reset a user's password |
|
||||||
|
37
docs/cli/notifications.md
generated
Normal file
37
docs/cli/notifications.md
generated
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<!-- DO NOT EDIT | GENERATED CONTENT -->
|
||||||
|
|
||||||
|
# notifications
|
||||||
|
|
||||||
|
Manage Coder notifications
|
||||||
|
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
- notification
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```console
|
||||||
|
coder notifications
|
||||||
|
```
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
```console
|
||||||
|
Administrators can use these commands to change notification settings.
|
||||||
|
- Pause Coder notifications. Administrators can temporarily stop notifiers from
|
||||||
|
dispatching messages in case of the target outage (for example: unavailable SMTP
|
||||||
|
server or Webhook not responding).:
|
||||||
|
|
||||||
|
$ coder notifications pause
|
||||||
|
|
||||||
|
- Resume Coder notifications:
|
||||||
|
|
||||||
|
$ coder notifications resume
|
||||||
|
```
|
||||||
|
|
||||||
|
## Subcommands
|
||||||
|
|
||||||
|
| Name | Purpose |
|
||||||
|
| ------------------------------------------------ | -------------------- |
|
||||||
|
| [<code>pause</code>](./notifications_pause.md) | Pause notifications |
|
||||||
|
| [<code>resume</code>](./notifications_resume.md) | Resume notifications |
|
11
docs/cli/notifications_pause.md
generated
Normal file
11
docs/cli/notifications_pause.md
generated
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<!-- DO NOT EDIT | GENERATED CONTENT -->
|
||||||
|
|
||||||
|
# notifications pause
|
||||||
|
|
||||||
|
Pause notifications
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```console
|
||||||
|
coder notifications pause
|
||||||
|
```
|
11
docs/cli/notifications_resume.md
generated
Normal file
11
docs/cli/notifications_resume.md
generated
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<!-- DO NOT EDIT | GENERATED CONTENT -->
|
||||||
|
|
||||||
|
# notifications resume
|
||||||
|
|
||||||
|
Resume notifications
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```console
|
||||||
|
coder notifications resume
|
||||||
|
```
|
@ -755,6 +755,21 @@
|
|||||||
"description": "Print network debug information for DERP and STUN",
|
"description": "Print network debug information for DERP and STUN",
|
||||||
"path": "cli/netcheck.md"
|
"path": "cli/netcheck.md"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": "notifications",
|
||||||
|
"description": "Manage Coder notifications",
|
||||||
|
"path": "cli/notifications.md"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "notifications pause",
|
||||||
|
"description": "Pause notifications",
|
||||||
|
"path": "cli/notifications_pause.md"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "notifications resume",
|
||||||
|
"description": "Resume notifications",
|
||||||
|
"path": "cli/notifications_resume.md"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "open",
|
"title": "open",
|
||||||
"description": "Open a workspace",
|
"description": "Open a workspace",
|
||||||
|
Reference in New Issue
Block a user