feat(cli): pause notifications (#13873)

This commit is contained in:
Marcin Tojek
2024-07-11 15:22:20 +02:00
committed by GitHub
parent f36b816391
commit bee913ac45
12 changed files with 313 additions and 3 deletions

85
cli/notifications.go Normal file
View 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
View 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
}

View File

@ -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(),
} }
} }

View File

@ -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

View 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.

View 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.

View 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.

View File

@ -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
View 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
View 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
View File

@ -0,0 +1,11 @@
<!-- DO NOT EDIT | GENERATED CONTENT -->
# notifications resume
Resume notifications
## Usage
```console
coder notifications resume
```

View File

@ -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",