Skip to content

Commit

Permalink
new silenced setting attributes addition
Browse files Browse the repository at this point in the history
Signed-off-by: Rajshekar Chavakula <[email protected]>
  • Loading branch information
chavakula committed Jan 31, 2024
1 parent 4731b2b commit b2bb21d
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 5 deletions.
7 changes: 7 additions & 0 deletions backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,13 @@ func Initialize(ctx context.Context, config *Config) (*Backend, error) {

// Create the store, which lives on top of etcd
stor := etcdstore.NewStore(b.Client, config.EtcdName)

// set config details
scfg := etcdstore.Config{}
scfg.DefaultSilencedExpiryTime = config.DefaultSilencedExpiryTime
scfg.MaxSilencedExpiryTimeAllowed = config.MaxSilencedExpiryTimeAllowed
etcdstore.SetConfig(scfg, stor)

b.Store = stor
storv2 := etcdstorev2.NewStore(b.Client)
var storev2Proxy storev2.Proxy
Expand Down
15 changes: 15 additions & 0 deletions backend/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ const (
flagLabels = "labels"
flagAnnotations = "annotations"

// silenced expiry flags
flagMaxSilencedExpiryTimeAllowed = "max-silenced-expiry-time-allowed"
flagDefaultSilencedExpiryTime = "default-silenced-expiry-time"

// Etcd flag constants
flagEtcdClientURLs = "etcd-client-urls"
flagEtcdListenClientURLs = "etcd-listen-client-urls"
Expand Down Expand Up @@ -255,6 +259,9 @@ func StartCommand(initialize InitializeFunc) *cobra.Command {
CacheDir: viper.GetString(flagCacheDir),
StateDir: viper.GetString(flagStateDir),

DefaultSilencedExpiryTime: viper.GetDuration(flagDefaultSilencedExpiryTime),
MaxSilencedExpiryTimeAllowed: viper.GetDuration(flagMaxSilencedExpiryTimeAllowed),

EtcdAdvertiseClientURLs: viper.GetStringSlice(flagEtcdAdvertiseClientURLs),
EtcdListenClientURLs: viper.GetStringSlice(flagEtcdListenClientURLs),
EtcdClientURLs: fallbackStringSlice(flagEtcdClientURLs, flagEtcdAdvertiseClientURLs),
Expand Down Expand Up @@ -448,6 +455,10 @@ func handleConfig(cmd *cobra.Command, arguments []string, server bool) error {
viper.SetDefault(flagEventLogBufferSize, 100000)
viper.SetDefault(flagEventLogFile, "")
viper.SetDefault(flagEventLogParallelEncoders, false)

// default silenced value are set for 1 day = 1440m
viper.SetDefault(flagMaxSilencedExpiryTimeAllowed, "1440m")
viper.SetDefault(flagDefaultSilencedExpiryTime, "1440m")
}

// Etcd defaults
Expand Down Expand Up @@ -583,6 +594,10 @@ func flagSet(server bool) *pflag.FlagSet {
flagSet.Duration(flagPlatformMetricsLoggingInterval, viper.GetDuration(flagPlatformMetricsLoggingInterval), "platform metrics logging interval")
flagSet.String(flagPlatformMetricsLogFile, viper.GetString(flagPlatformMetricsLogFile), "platform metrics log file path")

// silenced configuration flags
flagSet.Duration(flagDefaultSilencedExpiryTime, viper.GetDuration(flagDefaultSilencedExpiryTime), "Default expiry time for silenced if not set in minutes")
flagSet.Duration(flagMaxSilencedExpiryTimeAllowed, viper.GetDuration(flagMaxSilencedExpiryTimeAllowed), "Maximum expiry time allowed for silenced in minutes")

// Etcd server flags
flagSet.StringSlice(flagEtcdPeerURLs, viper.GetStringSlice(flagEtcdPeerURLs), "list of URLs to listen on for peer traffic")
_ = flagSet.SetAnnotation(flagEtcdPeerURLs, "categories", []string{"store"})
Expand Down
4 changes: 4 additions & 0 deletions backend/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,8 @@ type Config struct {
EventLogBufferWait time.Duration
EventLogFile string
EventLogParallelEncoders bool

// expiry setting for silences
DefaultSilencedExpiryTime time.Duration
MaxSilencedExpiryTimeAllowed time.Duration
}
16 changes: 16 additions & 0 deletions backend/store/etcd/silenced_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,13 @@ func (s *Store) UpdateSilencedEntry(ctx context.Context, silenced *corev2.Silenc
if err := silenced.Validate(); err != nil {
return &store.ErrNotValid{Err: err}
}
allowedMaxTime := time.Now().Add(s.cfg.MaxSilencedExpiryTimeAllowed).Unix()

// check for maximum allowed duration for silenced allowed
if silenced.ExpireAt > 0 && (silenced.ExpireAt > allowedMaxTime) {
err := errors.New("silenced crossed maximum duration allowed")
return &store.ErrThreshold{Err: err}
}

if silenced.ExpireAt == 0 && silenced.Expire > 0 {
start := time.Now()
Expand All @@ -216,6 +223,15 @@ func (s *Store) UpdateSilencedEntry(ctx context.Context, silenced *corev2.Silenc
silenced.ExpireAt = start.Add(time.Duration(silenced.Expire) * time.Second).Unix()
}

// set default silenced expiry time configured in backend yaml file
if silenced.Expire <= 0 && silenced.ExpireAt == 0 {
start := time.Now()
if silenced.Begin > 0 {
start = time.Unix(silenced.Begin, 0)
}
silenced.ExpireAt = start.Add(s.cfg.DefaultSilencedExpiryTime).Unix()
}

silencedBytes, err := proto.Marshal(silenced)
if err != nil {
return &store.ErrEncode{Err: err}
Expand Down
39 changes: 34 additions & 5 deletions backend/store/etcd/silenced_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,17 @@ func TestSilencedStorage(t *testing.T) {
assert.NoError(t, err)
assert.NotNil(t, entry)
assert.Equal(t, "subscription:*", entry.Name)
// Entries without expirations should return -1
assert.Equal(t, int64(-1), entry.Expire)

// check entries without -1 expiry
assert.NotEqual(t, int64(-1), entry.Expire)

// Delete silenced entry by name
err = store.DeleteSilencedEntryByName(ctx, silenced.Name)
assert.NoError(t, err)

// Update a silenced entry's expire time
silenced.Expire = 2
silenced.ExpireAt = 0
err = store.UpdateSilencedEntry(ctx, silenced)
assert.NoError(t, err)

Expand All @@ -100,6 +102,7 @@ func TestSilencedStorageWithExpire(t *testing.T) {
silenced := types.FixtureSilenced("subscription:checkname")
silenced.Namespace = "default"
silenced.Expire = 15
silenced.ExpireAt = 0
ctx := context.WithValue(context.Background(), types.NamespaceKey, silenced.Namespace)

err := store.UpdateSilencedEntry(ctx, silenced)
Expand All @@ -120,9 +123,9 @@ func TestSilencedStorageWithBegin(t *testing.T) {
silenced := types.FixtureSilenced("subscription:checkname")
silenced.Namespace = "default"
// set a begin time in the future
silenced.Begin = time.Date(1970, 01, 01, 01, 00, 00, 00, time.UTC).Unix()
silenced.Begin = time.Now().Add(time.Duration(1) * time.Second).Unix()
// current time is before the start time
currentTime := time.Date(1970, 01, 01, 00, 00, 00, 00, time.UTC).Unix()
currentTime := time.Now().Unix()
ctx := context.WithValue(context.Background(), types.NamespaceKey, silenced.Namespace)

err := store.UpdateSilencedEntry(ctx, silenced)
Expand All @@ -137,8 +140,11 @@ func TestSilencedStorageWithBegin(t *testing.T) {
require.NotNil(t, entry)
assert.False(t, entry.Begin < currentTime)

// Wait for begin time to elapse current time. i.e let silencing begin
time.Sleep(3 * time.Second)

// reset current time to be ahead of begin time
currentTime = time.Date(1970, 01, 01, 02, 00, 00, 00, time.UTC).Unix()
currentTime = time.Now().Unix()
assert.True(t, entry.Begin < currentTime)
})
}
Expand Down Expand Up @@ -168,3 +174,26 @@ func TestSilencedStorageWithBeginAndExpire(t *testing.T) {
assert.Equal(t, entry.Expire, int64(15))
})
}

func TestSilencedStorageWithMaxAllowedThresholdExpiry(t *testing.T) {
testWithEtcd(t, func(store store.Store) {
silenced := types.FixtureSilenced("subscription:checkname")
silenced.Namespace = "default"
silenced.ExpireAt = time.Now().Add(time.Duration(30000) * time.Second).Unix()
// set a begin time
silenced.Begin = time.Now().Unix()
ctx := context.WithValue(context.Background(), types.NamespaceKey, silenced.Namespace)

err := store.UpdateSilencedEntry(ctx, silenced)

// assert that error is thrown for breaching max expiry time allowed
assert.Error(t, err)

entry, err := store.GetSilencedEntryByName(ctx, silenced.Name)

// assert that entry is nil
assert.NoError(t, err)
assert.Nil(t, entry)

})
}
12 changes: 12 additions & 0 deletions backend/store/etcd/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"path"
"reflect"
"strings"
"time"

"github.com/gogo/protobuf/proto"
"github.com/sensu/sensu-go/backend/store"
Expand All @@ -22,10 +23,16 @@ const (
EtcdRoot = "/sensu.io"
)

type Config struct {
DefaultSilencedExpiryTime time.Duration
MaxSilencedExpiryTimeAllowed time.Duration
}

// Store is an implementation of the sensu-go/backend/store.Store iface.
type Store struct {
client *clientv3.Client
keepalivesPath string
cfg Config
}

// NewStore creates a new Store.
Expand All @@ -38,6 +45,11 @@ func NewStore(client *clientv3.Client, name string) *Store {
return store
}

// SetConfig adds Store configurations
func SetConfig(cfg Config, store *Store) {
store.cfg = cfg
}

// Create the given key with the serialized object.
func Create(ctx context.Context, client *clientv3.Client, key, namespace string, object interface{}) error {
bytes, err := marshal(object)
Expand Down
10 changes: 10 additions & 0 deletions backend/store/etcd/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"encoding/json"
"fmt"
"testing"
"time"

"github.com/gogo/protobuf/proto"
corev2 "github.com/sensu/core/v2"
Expand All @@ -28,6 +29,9 @@ func testWithEtcd(t *testing.T, f func(store.Store)) {

s := NewStore(client, e.Name())

s.cfg.MaxSilencedExpiryTimeAllowed = time.Duration(3000 * time.Second)
s.cfg.DefaultSilencedExpiryTime = time.Duration(3000 * time.Second)

// Mock a default namespace
require.NoError(t, s.CreateNamespace(context.Background(), types.FixtureNamespace("default")))

Expand All @@ -42,6 +46,9 @@ func testWithEtcdStore(t *testing.T, f func(*Store)) {

s := NewStore(client, e.Name())

s.cfg.MaxSilencedExpiryTimeAllowed = time.Duration(3000 * time.Second)
s.cfg.DefaultSilencedExpiryTime = time.Duration(3000 * time.Second)

// Mock a default namespace
require.NoError(t, s.CreateNamespace(context.Background(), types.FixtureNamespace("default")))

Expand All @@ -56,6 +63,9 @@ func testWithEtcdClient(t *testing.T, f func(store.Store, *clientv3.Client)) {

s := NewStore(client, e.Name())

s.cfg.MaxSilencedExpiryTimeAllowed = time.Duration(3000 * time.Second)
s.cfg.DefaultSilencedExpiryTime = time.Duration(3000 * time.Second)

// Mock a default namespace
require.NoError(t, s.CreateNamespace(context.Background(), types.FixtureNamespace("default")))

Expand Down
9 changes: 9 additions & 0 deletions backend/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ func (e *ErrNotFound) Error() string {
return fmt.Sprintf("key %s not found", e.Key)
}

// ErrThreshold is returned when configured thresholds are reached
type ErrThreshold struct {
Err error
}

func (e *ErrThreshold) Error() string {
return fmt.Sprintf("Threshold reached: %s", e.Err.Error())
}

// ErrNotValid is returned when an object failed validation
type ErrNotValid struct {
Err error
Expand Down

0 comments on commit b2bb21d

Please sign in to comment.