mirror of
https://github.com/prometheus/alertmanager
synced 2025-04-25 12:28:27 +00:00
provider/mesh: extract silence deletion into state
This commit is contained in:
parent
9039a3cffa
commit
3d350a34b5
@ -2,7 +2,6 @@ package mesh
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/prometheus/alertmanager/provider"
|
"github.com/prometheus/alertmanager/provider"
|
||||||
"github.com/prometheus/alertmanager/types"
|
"github.com/prometheus/alertmanager/types"
|
||||||
@ -161,31 +160,16 @@ func (s *Silences) Set(sil *types.Silence) (uuid.UUID, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Silences) Del(id uuid.UUID) error {
|
func (s *Silences) Del(id uuid.UUID) error {
|
||||||
s.st.mtx.RLock()
|
sil, err := s.st.del(id)
|
||||||
sil, ok := s.st.m[id]
|
if err != nil {
|
||||||
s.st.mtx.RUnlock()
|
return err
|
||||||
if !ok {
|
|
||||||
return provider.ErrNotFound
|
|
||||||
}
|
}
|
||||||
now := time.Now()
|
|
||||||
if sil.EndsAt.Before(now) {
|
|
||||||
return fmt.Errorf("silence already ended")
|
|
||||||
}
|
|
||||||
// Silences are immutable by contract so we create a completely
|
|
||||||
// new object instead.
|
|
||||||
newSil := *sil
|
|
||||||
newSil.UpdatedAt = now
|
|
||||||
newSil.EndsAt = now
|
|
||||||
|
|
||||||
if err := newSil.Init(); err != nil {
|
|
||||||
return fmt.Errorf("silence init: %s", err)
|
|
||||||
}
|
|
||||||
update := &silenceState{
|
update := &silenceState{
|
||||||
m: map[uuid.UUID]*types.Silence{
|
m: map[uuid.UUID]*types.Silence{
|
||||||
newSil.ID: &newSil,
|
sil.ID: sil,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
s.st.Merge(update)
|
|
||||||
s.send.GossipBroadcast(update)
|
s.send.GossipBroadcast(update)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/prometheus/alertmanager/provider"
|
||||||
"github.com/prometheus/alertmanager/types"
|
"github.com/prometheus/alertmanager/types"
|
||||||
"github.com/satori/go.uuid"
|
"github.com/satori/go.uuid"
|
||||||
"github.com/weaveworks/mesh"
|
"github.com/weaveworks/mesh"
|
||||||
@ -133,11 +134,10 @@ func (st *silenceState) Encode() [][]byte {
|
|||||||
|
|
||||||
// silenceModAllowed checks whether silence a may be changed to silence b.
|
// silenceModAllowed checks whether silence a may be changed to silence b.
|
||||||
// Returns an error stating the reason if not.
|
// Returns an error stating the reason if not.
|
||||||
func (st *silenceState) silenceModAllowed(a, b *types.Silence) error {
|
func silenceModAllowed(a, b *types.Silence, now time.Time) error {
|
||||||
if !b.StartsAt.Equal(a.StartsAt) {
|
if !b.StartsAt.Equal(a.StartsAt) {
|
||||||
return fmt.Errorf("silence start time must not be modified")
|
return fmt.Errorf("silence start time must not be modified")
|
||||||
}
|
}
|
||||||
now := st.now()
|
|
||||||
if a.EndsAt.Before(now) {
|
if a.EndsAt.Before(now) {
|
||||||
return fmt.Errorf("end time must not be modified for elapsed silence")
|
return fmt.Errorf("end time must not be modified for elapsed silence")
|
||||||
}
|
}
|
||||||
@ -154,7 +154,8 @@ func (st *silenceState) set(s *types.Silence) error {
|
|||||||
st.mtx.Lock()
|
st.mtx.Lock()
|
||||||
defer st.mtx.Unlock()
|
defer st.mtx.Unlock()
|
||||||
|
|
||||||
s.UpdatedAt = st.now()
|
now := st.now()
|
||||||
|
s.UpdatedAt = now
|
||||||
|
|
||||||
if err := s.Validate(); err != nil {
|
if err := s.Validate(); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -165,13 +166,39 @@ func (st *silenceState) set(s *types.Silence) error {
|
|||||||
st.m[s.ID] = s
|
st.m[s.ID] = s
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if err := st.silenceModAllowed(prev, s); err != nil {
|
if err := silenceModAllowed(prev, s, now); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
st.m[s.ID] = s
|
st.m[s.ID] = s
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (st *silenceState) del(id uuid.UUID) (*types.Silence, error) {
|
||||||
|
st.mtx.Lock()
|
||||||
|
defer st.mtx.Unlock()
|
||||||
|
|
||||||
|
prev, ok := st.m[id]
|
||||||
|
if !ok {
|
||||||
|
return nil, provider.ErrNotFound
|
||||||
|
}
|
||||||
|
// Silences are immutable by contract so we create a
|
||||||
|
// shallow copy.
|
||||||
|
sil := *prev
|
||||||
|
now := st.now()
|
||||||
|
sil.UpdatedAt = now
|
||||||
|
sil.EndsAt = now
|
||||||
|
|
||||||
|
if err := sil.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := silenceModAllowed(prev, &sil, now); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
st.m[sil.ID] = &sil
|
||||||
|
return &sil, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (st *silenceState) Merge(other mesh.GossipData) mesh.GossipData {
|
func (st *silenceState) Merge(other mesh.GossipData) mesh.GossipData {
|
||||||
o := other.(*silenceState)
|
o := other.(*silenceState)
|
||||||
o.mtx.RLock()
|
o.mtx.RLock()
|
||||||
|
@ -16,6 +16,7 @@ package types
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -276,6 +277,7 @@ func (s *Silence) Init() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sort.Sort(s.Matchers)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user