2016-11-04 00:44:28 +00:00
|
|
|
package bolt
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"github.com/boltdb/bolt"
|
|
|
|
"github.com/influxdata/chronograf"
|
|
|
|
"github.com/influxdata/chronograf/bolt/internal"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Ensure AlertsStore implements chronograf.AlertsStore.
|
|
|
|
var _ chronograf.AlertRulesStore = &AlertsStore{}
|
|
|
|
|
2017-03-06 16:11:52 +00:00
|
|
|
// AlertsBucket is the name of the bucket alert configuration is stored in
|
2016-11-04 00:44:28 +00:00
|
|
|
var AlertsBucket = []byte("Alerts")
|
|
|
|
|
2017-03-06 16:11:52 +00:00
|
|
|
// AlertsStore represents the bolt implementation of a store for alerts
|
2016-11-04 00:44:28 +00:00
|
|
|
type AlertsStore struct {
|
|
|
|
client *Client
|
|
|
|
}
|
|
|
|
|
|
|
|
// All returns all known alerts
|
2016-11-04 01:56:42 +00:00
|
|
|
func (s *AlertsStore) All(ctx context.Context, sourceID, kapaID int) ([]chronograf.AlertRule, error) {
|
2016-11-04 00:44:28 +00:00
|
|
|
var srcs []chronograf.AlertRule
|
|
|
|
if err := s.client.db.View(func(tx *bolt.Tx) error {
|
|
|
|
if err := tx.Bucket(AlertsBucket).ForEach(func(k, v []byte) error {
|
2016-11-04 01:56:42 +00:00
|
|
|
var src internal.ScopedAlert
|
2016-11-04 00:44:28 +00:00
|
|
|
if err := internal.UnmarshalAlertRule(v, &src); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-11-04 01:56:42 +00:00
|
|
|
// filter by only those rules with these ids
|
|
|
|
if src.KapaID == kapaID && src.SrcID == sourceID {
|
|
|
|
srcs = append(srcs, src.AlertRule)
|
|
|
|
}
|
2016-11-04 00:44:28 +00:00
|
|
|
return nil
|
|
|
|
}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return srcs, nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add creates a new Alerts in the AlertsStore.
|
2016-11-04 01:56:42 +00:00
|
|
|
func (s *AlertsStore) Add(ctx context.Context, sourceID, kapaID int, src chronograf.AlertRule) (chronograf.AlertRule, error) {
|
2016-11-04 00:44:28 +00:00
|
|
|
if err := s.client.db.Update(func(tx *bolt.Tx) error {
|
|
|
|
b := tx.Bucket(AlertsBucket)
|
2016-11-04 01:56:42 +00:00
|
|
|
scoped := internal.ScopedAlert{
|
|
|
|
AlertRule: src,
|
|
|
|
SrcID: sourceID,
|
|
|
|
KapaID: kapaID,
|
|
|
|
}
|
|
|
|
if v, err := internal.MarshalAlertRule(&scoped); err != nil {
|
2016-11-04 00:44:28 +00:00
|
|
|
return err
|
|
|
|
} else if err := b.Put([]byte(src.ID), v); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}); err != nil {
|
|
|
|
return chronograf.AlertRule{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return src, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete removes the Alerts from the AlertsStore
|
2016-11-04 01:56:42 +00:00
|
|
|
func (s *AlertsStore) Delete(ctx context.Context, srcID, kapaID int, src chronograf.AlertRule) error {
|
|
|
|
_, err := s.Get(ctx, srcID, kapaID, src.ID)
|
2016-11-04 00:44:28 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-11-04 01:56:42 +00:00
|
|
|
|
2016-11-04 00:44:28 +00:00
|
|
|
if err := s.client.db.Update(func(tx *bolt.Tx) error {
|
|
|
|
if err := tx.Bucket(AlertsBucket).Delete([]byte(src.ID)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-11-04 01:56:42 +00:00
|
|
|
// scopedGet returns a Alerts if the id exists.
|
|
|
|
func (s *AlertsStore) scopedGet(ctx context.Context, id string) (internal.ScopedAlert, error) {
|
|
|
|
var src internal.ScopedAlert
|
2016-11-04 00:44:28 +00:00
|
|
|
if err := s.client.db.View(func(tx *bolt.Tx) error {
|
|
|
|
if v := tx.Bucket(AlertsBucket).Get([]byte(id)); v == nil {
|
|
|
|
return chronograf.ErrAlertNotFound
|
|
|
|
} else if err := internal.UnmarshalAlertRule(v, &src); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}); err != nil {
|
2016-11-04 01:56:42 +00:00
|
|
|
return internal.ScopedAlert{}, err
|
2016-11-04 00:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return src, nil
|
|
|
|
}
|
|
|
|
|
2016-11-04 01:56:42 +00:00
|
|
|
// Get returns a Alerts if the id exists.
|
|
|
|
func (s *AlertsStore) Get(ctx context.Context, srcID, kapaID int, id string) (chronograf.AlertRule, error) {
|
|
|
|
scoped, err := s.scopedGet(ctx, id)
|
|
|
|
if err != nil {
|
|
|
|
return chronograf.AlertRule{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if scoped.SrcID != srcID || scoped.KapaID != kapaID {
|
|
|
|
return chronograf.AlertRule{}, chronograf.ErrAlertNotFound
|
|
|
|
}
|
|
|
|
return scoped.AlertRule, nil
|
|
|
|
}
|
|
|
|
|
2016-11-04 00:44:28 +00:00
|
|
|
// Update a Alerts
|
2016-11-04 01:56:42 +00:00
|
|
|
func (s *AlertsStore) Update(ctx context.Context, srcID, kapaID int, src chronograf.AlertRule) error {
|
|
|
|
// Check if we have permissions to get this alert
|
|
|
|
_, err := s.Get(ctx, srcID, kapaID, src.ID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2016-11-04 00:44:28 +00:00
|
|
|
if err := s.client.db.Update(func(tx *bolt.Tx) error {
|
|
|
|
// Get an existing alerts with the same ID.
|
|
|
|
b := tx.Bucket(AlertsBucket)
|
2016-11-04 01:56:42 +00:00
|
|
|
scoped := internal.ScopedAlert{
|
|
|
|
AlertRule: src,
|
|
|
|
SrcID: srcID,
|
|
|
|
KapaID: kapaID,
|
2016-11-04 00:44:28 +00:00
|
|
|
}
|
2016-11-04 01:56:42 +00:00
|
|
|
if v, err := internal.MarshalAlertRule(&scoped); err != nil {
|
2016-11-04 00:44:28 +00:00
|
|
|
return err
|
|
|
|
} else if err := b.Put([]byte(src.ID), v); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|