Skip to content

Commit

Permalink
Add Alerting Contact Points
Browse files Browse the repository at this point in the history
  • Loading branch information
safaci2000 committed Oct 17, 2024
1 parent 51e78d0 commit 7886b3d
Show file tree
Hide file tree
Showing 46 changed files with 1,108 additions and 67 deletions.
34 changes: 34 additions & 0 deletions cli/backup/alerting.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package backup

import (
"context"

"github.com/bep/simplecobra"
"github.com/esnet/gdg/cli/support"
"github.com/spf13/cobra"
)

func newAlertingCommand() simplecobra.Commander {
description := "Manage Alerting resources"
return &support.SimpleCommand{
NameP: "alerting",
Short: description,
Long: description,
WithCFunc: func(cmd *cobra.Command, r *support.RootCommand) {
cmd.Aliases = []string{"alert"}
// connections := cmd
// connections.PersistentFlags().StringP("connection", "", "", "filter by connection slug")
},
CommandsList: []simplecobra.Commander{
newAlertingContactCommand(),
// newClearConnectionsCmd(),
// newUploadConnectionsCmd(),
// newDownloadConnectionsCmd(),
// newListConnectionsCmd(),
// newConnectionsPermissionCmd(),
},
RunFunc: func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *support.RootCommand, args []string) error {
return cd.CobraCommand.Help()
},

Check warning on line 32 in cli/backup/alerting.go

View check run for this annotation

Codecov / codecov/patch

cli/backup/alerting.go#L30-L32

Added lines #L30 - L32 were not covered by tests
}
}
158 changes: 158 additions & 0 deletions cli/backup/alerting_contacts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package backup

import (
"context"
"encoding/json"
"log"
"log/slog"

"github.com/bep/simplecobra"
"github.com/esnet/gdg/cli/support"
"github.com/esnet/gdg/internal/service"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra"
)

func newAlertingContactCommand() simplecobra.Commander {
description := "Manage Alerting ContactPoints "
return &support.SimpleCommand{
NameP: "contactpoint",
Short: description,
Long: description,
WithCFunc: func(cmd *cobra.Command, r *support.RootCommand) {
cmd.Aliases = []string{"contact", "contacts", "contactpoints"}
},
CommandsList: []simplecobra.Commander{
newListContactPointsCmd(),
newClearContactPointsCmd(),
newUploadContactPointsCmd(),
newDownloadContactPointsCmd(),
},
RunFunc: func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *support.RootCommand, args []string) error {
return cd.CobraCommand.Help()
},

Check warning on line 33 in cli/backup/alerting_contacts.go

View check run for this annotation

Codecov / codecov/patch

cli/backup/alerting_contacts.go#L31-L33

Added lines #L31 - L33 were not covered by tests
}
}

func newListContactPointsCmd() simplecobra.Commander {
description := "List all contact points for the given Organization"
return &support.SimpleCommand{
NameP: "list",
Short: description,
Long: description,
WithCFunc: func(cmd *cobra.Command, r *support.RootCommand) {
cmd.Aliases = []string{"l"}
},
RunFunc: func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *support.RootCommand, args []string) error {
rootCmd.TableObj.AppendHeader(table.Row{"uid", "name", "slug", "type", "provenance", "settings"})
contactPoints, err := rootCmd.GrafanaSvc().ListContactPoints()
slog.Info("Listing contact points for context",
slog.String("Organization", GetOrganizationName()),
slog.String("context", GetContext()))
slog.Warn("GDG does not manage the 'email receiver' entity. It has a very odd behavior compared to all " +
"other entities. If you need to manage email contacts, please create a new contact. GDG will ignore the default contact.")
if err != nil {
log.Fatal("unable to retrieve Orgs contact points", slog.Any("err", err))
}

Check warning on line 56 in cli/backup/alerting_contacts.go

View check run for this annotation

Codecov / codecov/patch

cli/backup/alerting_contacts.go#L55-L56

Added lines #L55 - L56 were not covered by tests
if len(contactPoints) == 0 {
slog.Info("No contact points found")
} else {
for _, link := range contactPoints {
rawBytes, err := json.Marshal(link.Settings)
if err != nil {
slog.Warn("unable to marshall settings to valid JSON")
}

Check warning on line 64 in cli/backup/alerting_contacts.go

View check run for this annotation

Codecov / codecov/patch

cli/backup/alerting_contacts.go#L63-L64

Added lines #L63 - L64 were not covered by tests
typeVal := ""
if link.Type != nil {
typeVal = *link.Type
}
rootCmd.TableObj.AppendRow(table.Row{link.UID, link.Name, service.GetSlug(link.Name), typeVal, link.Provenance, string(rawBytes)})
}
rootCmd.Render(cd.CobraCommand, contactPoints)
}
return nil
},
}
}

func newDownloadContactPointsCmd() simplecobra.Commander {
description := "Download all contact points for the given Organization"
return &support.SimpleCommand{
NameP: "download",
Short: description,
Long: description,
WithCFunc: func(cmd *cobra.Command, r *support.RootCommand) {
cmd.Aliases = []string{"d"}
},
RunFunc: func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *support.RootCommand, args []string) error {
file, err := rootCmd.GrafanaSvc().DownloadContactPoints()
slog.Info("Download contact points for context",
slog.String("Organization", GetOrganizationName()),
slog.String("context", GetContext()))
if err != nil {
slog.Error("unable to contact point")
} else {
slog.Info("contact points successfully downloaded", slog.Any("file", file))
}
return nil

Check warning on line 97 in cli/backup/alerting_contacts.go

View check run for this annotation

Codecov / codecov/patch

cli/backup/alerting_contacts.go#L87-L97

Added lines #L87 - L97 were not covered by tests
},
}
}

func newUploadContactPointsCmd() simplecobra.Commander {
description := "Upload all contact points for the given Organization"
return &support.SimpleCommand{
NameP: "upload",
Short: description,
Long: description,
WithCFunc: func(cmd *cobra.Command, r *support.RootCommand) {
cmd.Aliases = []string{"u"}
},
RunFunc: func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *support.RootCommand, args []string) error {
newItems, err := rootCmd.GrafanaSvc().UploadContactPoints()
slog.Info("Upload contact points for context",
slog.String("Organization", GetOrganizationName()),
slog.String("context", GetContext()))
if err != nil {
slog.Error("unable to upload contact points", slog.Any("err", err))
} else {
slog.Info("contact points successfully uploaded")
rootCmd.TableObj.AppendHeader(table.Row{"name"})
for _, item := range newItems {
rootCmd.TableObj.AppendRow(table.Row{item})
}

Check warning on line 123 in cli/backup/alerting_contacts.go

View check run for this annotation

Codecov / codecov/patch

cli/backup/alerting_contacts.go#L111-L123

Added lines #L111 - L123 were not covered by tests

rootCmd.Render(cd.CobraCommand, newItems)

Check warning on line 125 in cli/backup/alerting_contacts.go

View check run for this annotation

Codecov / codecov/patch

cli/backup/alerting_contacts.go#L125

Added line #L125 was not covered by tests
}
return nil

Check warning on line 127 in cli/backup/alerting_contacts.go

View check run for this annotation

Codecov / codecov/patch

cli/backup/alerting_contacts.go#L127

Added line #L127 was not covered by tests
},
}
}

func newClearContactPointsCmd() simplecobra.Commander {
description := "Clear all contact points for the given Organization"
return &support.SimpleCommand{
NameP: "clear",
Short: description,
Long: description,
WithCFunc: func(cmd *cobra.Command, r *support.RootCommand) {
cmd.Aliases = []string{"l"}
},
RunFunc: func(ctx context.Context, cd *simplecobra.Commandeer, rootCmd *support.RootCommand, args []string) error {
removedItems, err := rootCmd.GrafanaSvc().ClearContactPoints()
slog.Info("Clear contact points for context",
slog.String("Organization", GetOrganizationName()),
slog.String("context", GetContext()))
if err != nil {
slog.Error("unable to contact point")
} else {
slog.Info("contact points successfully removed")
rootCmd.TableObj.AppendHeader(table.Row{"name"})
for _, item := range removedItems {
rootCmd.TableObj.AppendRow(table.Row{item})
}

Check warning on line 153 in cli/backup/alerting_contacts.go

View check run for this annotation

Codecov / codecov/patch

cli/backup/alerting_contacts.go#L141-L153

Added lines #L141 - L153 were not covered by tests
}
return nil

Check warning on line 155 in cli/backup/alerting_contacts.go

View check run for this annotation

Codecov / codecov/patch

cli/backup/alerting_contacts.go#L155

Added line #L155 was not covered by tests
},
}
}
1 change: 1 addition & 0 deletions cli/backup/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ limited to clear/delete, list, download and upload. Any other functionality wil
newOrganizationsCommand(),
newTeamsCommand(),
newUsersCommand(),
newAlertingCommand(),
},
}
}
Expand Down
4 changes: 3 additions & 1 deletion cli/commandeer.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ func Execute(defaultCfg string, args []string, options ...support.RootOption) er
cd, err := x.Execute(context.Background(), args)

if err != nil || len(args) == 0 {
_ = cd.CobraCommand.Help()
if cd != nil {
_ = cd.CobraCommand.Help()
}
return err
}

Expand Down
92 changes: 92 additions & 0 deletions cli/test/backup/alerting_contactpoints_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package backup

import (
"io"
"strings"
"testing"

"github.com/esnet/gdg/cli"
"github.com/esnet/gdg/cli/support"
"github.com/esnet/gdg/internal/service"
"github.com/esnet/gdg/internal/service/mocks"
"github.com/esnet/gdg/internal/tools/ptr"
"github.com/esnet/gdg/pkg/test_tooling"
"github.com/esnet/gdg/pkg/test_tooling/common"
"github.com/grafana/grafana-openapi-client-go/models"
"github.com/stretchr/testify/assert"
)

func TestContactPoints(t *testing.T) {
getOptionMockSvc := func(testSvc *mocks.GrafanaService) func() support.RootOption {
return func() support.RootOption {
return func(response *support.RootCommand) {
response.GrafanaSvc = func() service.GrafanaService {
return testSvc
}
}
}
}

t.Run("NoDataTest", func(t *testing.T) {
testSvc := new(mocks.GrafanaService)
testSvc.EXPECT().InitOrganizations().Return()
testSvc.EXPECT().ListContactPoints().Return(nil, nil)
optionMockSvc := getOptionMockSvc(testSvc)
r, w, cleanup := test_tooling.InterceptStdout()
defer cleanup()

err := cli.Execute(common.DefaultTestConfig, []string{"backup", "alerting", "contactpoint", "list"}, optionMockSvc())
assert.Nil(t, err)
defer cleanup()
w.Close()

out, _ := io.ReadAll(r)
outStr := string(out)
assert.True(t, strings.Contains(outStr, "WRN GDG does not manage the 'email receiver' entity."))
assert.True(t, strings.Contains(outStr, "No contact points found"))
})
t.Run("ListingTest", func(t *testing.T) {
testSvc := new(mocks.GrafanaService)
getMockSvc := func() service.GrafanaService {
return testSvc
}
resp := []*models.EmbeddedContactPoint{
{
Name: "Discord",
Type: ptr.Of("discordType"),
Settings: map[string]any{"token": "secret", "someValue": "result"},
},
{
Name: "Slack",
Type: ptr.Of("slackType"),
Settings: map[string]any{"token": "secret", "slack": "rocks"},
},
}

testSvc.EXPECT().InitOrganizations().Return()
testSvc.EXPECT().ListContactPoints().Return(resp, nil)

optionMockSvc := func() support.RootOption {
return func(response *support.RootCommand) {
response.GrafanaSvc = getMockSvc
}
}
r, w, cleanup := test_tooling.InterceptStdout()
defer cleanup()

err := cli.Execute(common.DefaultTestConfig, []string{"backup", "alerting", "contactpoint", "list"}, optionMockSvc())
assert.Nil(t, err)
defer cleanup()
w.Close()

out, _ := io.ReadAll(r)
outStr := string(out)
assert.True(t, strings.Contains(outStr, "WRN GDG does not manage the 'email receiver' entity."))
assert.True(t, strings.Contains(outStr, "PROVENANCE"))
assert.True(t, strings.Contains(outStr, "Discord"))
assert.True(t, strings.Contains(outStr, "Slack"))
// validate Type
assert.True(t, strings.Contains(outStr, "discordType"))
assert.True(t, strings.Contains(outStr, "slackType"))
})
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package test
package backup

import (
"io"
"strings"
"testing"

"github.com/esnet/gdg/pkg/test_tooling"

"github.com/esnet/gdg/cli"
"github.com/esnet/gdg/cli/support"
"github.com/esnet/gdg/internal/service"
Expand Down Expand Up @@ -38,7 +40,7 @@ func TestConnectionCommand(t *testing.T) {
response.GrafanaSvc = getMockSvc
}
}
r, w, cleanup := InterceptStdout()
r, w, cleanup := test_tooling.InterceptStdout()

err := cli.Execute(common.DefaultTestConfig, []string{"backup", "connections", "list"}, optionMockSvc())
assert.Nil(t, err)
Expand Down
18 changes: 18 additions & 0 deletions cli/test/backup/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package backup

import (
"log"
"os"
"testing"

"github.com/esnet/gdg/pkg/test_tooling/path"
)

func TestMain(m *testing.M) {
err := path.FixTestDir("backup", "../../..")
if err != nil {
log.Fatal(err.Error())
}
code := m.Run()
os.Exit(code)
}
12 changes: 7 additions & 5 deletions cli/test/devel_test.go → cli/test/tools/devel_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package test
package tools

import (
"strings"
"testing"

"github.com/esnet/gdg/pkg/test_tooling"

"github.com/esnet/gdg/cli"
"github.com/esnet/gdg/cli/support"
"github.com/esnet/gdg/internal/service/mocks"
Expand All @@ -21,7 +23,7 @@ func TestDevelSrvInfo(t *testing.T) {
err := cli.Execute(string(data), []string{"tools", "devel", "srvinfo"}, optionMockSvc())
return err
}
outStr, closeReader := setupAndExecuteMockingServices(t, execMe)
outStr, closeReader := test_tooling.SetupAndExecuteMockingServices(t, execMe)
defer closeReader()

assert.True(t, strings.Contains(outStr, "Version="))
Expand All @@ -37,15 +39,15 @@ func TestDevelSrvCompletion(t *testing.T) {
}
}

outStr, closeReader := setupAndExecuteMockingServices(t, fn([]string{"tools", "devel", "completion", "fish"}))
outStr, closeReader := test_tooling.SetupAndExecuteMockingServices(t, fn([]string{"tools", "devel", "completion", "fish"}))
assert.True(t, strings.Contains(outStr, "fish"))
assert.True(t, strings.Contains(outStr, "__completion_prepare_completions"))
closeReader()
outStr, closeReader = setupAndExecuteMockingServices(t, fn([]string{"tools", "devel", "completion", "bash"}))
outStr, closeReader = test_tooling.SetupAndExecuteMockingServices(t, fn([]string{"tools", "devel", "completion", "bash"}))
assert.True(t, strings.Contains(outStr, "bash"))
assert.True(t, strings.Contains(outStr, "flag_parsing_disabled"))
closeReader()
outStr, closeReader = setupAndExecuteMockingServices(t, fn([]string{"tools", "devel", "completion", "zsh"}))
outStr, closeReader = test_tooling.SetupAndExecuteMockingServices(t, fn([]string{"tools", "devel", "completion", "zsh"}))
assert.True(t, strings.Contains(outStr, "shellCompDirectiveKeepOrder"))
closeReader()
}
Loading

0 comments on commit 7886b3d

Please sign in to comment.