Skip to content

Commit

Permalink
chore: use datemath for notification silence
Browse files Browse the repository at this point in the history
  • Loading branch information
adityathebe committed Sep 11, 2024
1 parent dc2b1ec commit a2d4c63
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 38 deletions.
2 changes: 1 addition & 1 deletion db/notifications.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func NotificationSendSummary(ctx context.Context, id string, window time.Duratio
func GetMatchingNotificationSilencesCount(ctx context.Context, resources models.NotificationSilenceResource) (int64, error) {
_ = ctx.DB().Use(extraClausePlugin.New())

query := ctx.DB().Debug().Model(&models.NotificationSilence{})
query := ctx.DB().Model(&models.NotificationSilence{})

// Initialize with a false condition,
// if no resources are provided, the query won't return all records
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ require (
github.com/containrrr/shoutrrr v0.8.0
github.com/fergusstrange/embedded-postgres v1.25.0 // indirect
github.com/flanksource/commons v1.29.10
github.com/flanksource/duty v1.0.634
github.com/flanksource/duty v1.0.637
github.com/flanksource/gomplate/v3 v3.24.30
github.com/flanksource/kopper v1.0.9
github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -877,8 +877,8 @@ github.com/flanksource/artifacts v1.0.14 h1:Vv70bccsae0MwGaf/uSPp34J5V1/PyKfct9z
github.com/flanksource/artifacts v1.0.14/go.mod h1:qHVCnQu5k50aWNJ5UhpcAKEl7pAzqUrFFKGSm147G70=
github.com/flanksource/commons v1.29.10 h1:T/S95Pl8kASEFvQjQ7fJjTUqeVdhxQXg1vfkULTYFJQ=
github.com/flanksource/commons v1.29.10/go.mod h1:iTbrXOSp3Spv570Nly97D/U9cQjLZoVlmWCXqWzsvRU=
github.com/flanksource/duty v1.0.634 h1:plZxB4f9nSmR/57G06ML9lwYbAJPmdpQnFmbQuUvaVs=
github.com/flanksource/duty v1.0.634/go.mod h1:Oj9zIX94CR2U+nmnt97gNLMrsBWILyIhIBeJynIIgqE=
github.com/flanksource/duty v1.0.637 h1:VmJJxSNyyyJ84KJOi1BtHN7zIldad7mZk/PD6Pf6J+o=
github.com/flanksource/duty v1.0.637/go.mod h1:Oj9zIX94CR2U+nmnt97gNLMrsBWILyIhIBeJynIIgqE=
github.com/flanksource/gomplate/v3 v3.20.4/go.mod h1:27BNWhzzSjDed1z8YShO6W+z6G9oZXuxfNFGd/iGSdc=
github.com/flanksource/gomplate/v3 v3.24.30 h1:6Y25KnAMX4iCuEXe1C8d1kB2PdV+zD1ZulZrv6DV14Q=
github.com/flanksource/gomplate/v3 v3.24.30/go.mod h1:/lAM7+fkcCCfghCAjzdCqwgWxN5Ow8Sk6nkdFPjejCE=
Expand Down
5 changes: 3 additions & 2 deletions notification/controllers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"net/http"

"github.com/flanksource/duty/api"
"github.com/flanksource/duty/context"
echoSrv "github.com/flanksource/incident-commander/echo"
"github.com/flanksource/incident-commander/rbac"
Expand All @@ -30,9 +31,9 @@ func RegisterRoutes(e *echo.Echo) {
}

if err := SaveNotificationSilence(ctx, req); err != nil {
return err
return api.WriteError(c, err)
}

return nil
}, rbac.Authorization(rbac.ObjectNotificationSilence, rbac.ActionCreate))
}, rbac.Authorization(rbac.ObjectNotification, rbac.ActionCreate))
}
55 changes: 32 additions & 23 deletions notification/silence.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,51 @@ import (
"errors"
"time"

"github.com/flanksource/commons/duration"
"github.com/flanksource/duty/api"
"github.com/flanksource/duty/context"
"github.com/flanksource/duty/db"
"github.com/flanksource/duty/models"
"github.com/samber/lo"
"github.com/timberio/go-datemath"
)

type SilenceSaveRequest struct {
models.NotificationSilenceResource
From time.Time `json:"from"`
Until time.Time `json:"until"`
Duration string `json:"duration"`
Description string `json:"description"`
From string `json:"from"`
Until string `json:"until"`
Description string `json:"description"`
Recursive bool `json:"recursive"`

from time.Time
until time.Time
}

func (t *SilenceSaveRequest) Validate() error {
if t.From.IsZero() {
if t.From == "" {
return errors.New("`from` time is required")
}

if t.Until.IsZero() {
if t.Duration == "" {
return errors.New("`until` or `duration` is required")
}
if t.Until == "" {
return errors.New("`until` is required")
}

if parsed, err := duration.ParseDuration(t.Duration); err != nil {
return err
} else {
t.Until = t.From.Add(time.Duration(parsed))
}
if parsedTime, err := datemath.ParseAndEvaluate(t.From); err != nil {
return err
} else {
t.from = parsedTime
}

if t.From.After(t.Until) {
return errors.New("`from` time must be before `until` time")
if parsedTime, err := datemath.ParseAndEvaluate(t.Until); err != nil {
return err
} else {
t.until = parsedTime
}

if t.from.After(t.until) {
return errors.New("`from` time must be before `until")
}

if t.NotificationSilenceResource.CanaryID == nil && t.NotificationSilenceResource.CheckID == nil && t.NotificationSilenceResource.ConfigID == nil &&
t.NotificationSilenceResource.ComponentID == nil {
if t.NotificationSilenceResource.Empty() {
return errors.New("at least one of `config_id`, `canary_id`, `check_id` or `component_id` is required")
}

Expand All @@ -49,19 +57,20 @@ func (t *SilenceSaveRequest) Validate() error {

func SaveNotificationSilence(ctx context.Context, req SilenceSaveRequest) error {
if err := req.Validate(); err != nil {
return err
return api.Errorf(api.EINVALID, err.Error())
}

silence := models.NotificationSilence{
NotificationSilenceResource: req.NotificationSilenceResource,
From: req.From,
Until: req.Until,
From: req.from,
Until: req.until,
Description: req.Description,
Recursive: req.Recursive,
Source: models.SourceUI,
CreatedBy: lo.ToPtr(ctx.User().ID),
}

return ctx.DB().Create(&silence).Error
return db.ErrorDetails(ctx.DB().Create(&silence).Error)
}

func getSilencedResourceFromCelEnv(celEnv map[string]any) models.NotificationSilenceResource {
Expand Down
91 changes: 91 additions & 0 deletions notification/silence_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package notification

import (
"testing"
"time"

"github.com/flanksource/duty/models"
"github.com/google/uuid"
"github.com/samber/lo"
)

func TestSilenceSaveRequest_Validate(t *testing.T) {
type fields struct {
NotificationSilenceResource models.NotificationSilenceResource
From string
Until string
Description string
from time.Time
until time.Time
}
tests := []struct {
name string
fields fields
wantErr bool
}{
{
name: "empty from",
fields: fields{
NotificationSilenceResource: models.NotificationSilenceResource{},
From: "",
Until: "now+2d",
},
wantErr: true,
},
{
name: "empty until",
fields: fields{
NotificationSilenceResource: models.NotificationSilenceResource{},
From: "now",
Until: "",
},
wantErr: true,
},
{
name: "empty resource",
fields: fields{
NotificationSilenceResource: models.NotificationSilenceResource{},
From: "now",
Until: "now+2d",
},
wantErr: true,
},
{
name: "valid",
fields: fields{
NotificationSilenceResource: models.NotificationSilenceResource{
ConfigID: lo.ToPtr(uuid.NewString()),
},
From: "now",
Until: "now+2d",
},
},
{
name: "complete but invalid",
fields: fields{
NotificationSilenceResource: models.NotificationSilenceResource{
ConfigID: lo.ToPtr(uuid.NewString()),
},
From: "now",
Until: "now-1m",
},
wantErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tr := &SilenceSaveRequest{
NotificationSilenceResource: tt.fields.NotificationSilenceResource,
From: tt.fields.From,
Until: tt.fields.Until,
Description: tt.fields.Description,
from: tt.fields.from,
until: tt.fields.until,
}
if err := tr.Validate(); (err != nil) != tt.wantErr {
t.Fatalf("SilenceSaveRequest.Validate() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
18 changes: 9 additions & 9 deletions rbac/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,15 @@ const (
RoleAgent = "agent"

// Actions
ActionRead = "read"
ActionUpdate = "update"
ActionCreate = "create"
ActionDelete = "delete"
ActionRun = "run"
ActionApprove = "approve"
ActionAll = "*"
ActionCRUD = "create,read,update,delete"

ActionRead = "read"
ActionUpdate = "update"
ActionCreate = "create"
ActionDelete = "delete"
ActionRun = "run"
ActionApprove = "approve"
ActionAll = "*"
ActionCRUD = "create,read,update,delete"
ObjectKubernetesProxy = "kubernetes-proxy"
// Objects
ObjectLogs = "logs"
ObjectAgent = "agent"
Expand Down

0 comments on commit a2d4c63

Please sign in to comment.