Skip to content

Commit d48061a

Browse files
authored
Silenced cleanup (#5127)
* Add silenced store support to entity deletion logic * Refactor silenced store mock methods to include parameters for subscription and check name
1 parent f6b475e commit d48061a

File tree

10 files changed

+111
-21
lines changed

10 files changed

+111
-21
lines changed

backend/api/entity.go

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,28 @@ import (
1515

1616
// EntityClient is an API client for entities.
1717
type EntityClient struct {
18-
storev2 storev2.Interface
19-
entityStore store.EntityStore
20-
eventStore store.EventStore
21-
auth authorization.Authorizer
18+
storev2 storev2.Interface
19+
entityStore store.EntityStore
20+
eventStore store.EventStore
21+
silencedStore store.SilencedStore
22+
auth authorization.Authorizer
2223
}
2324

2425
// NewEntityClient creates a new EntityClient given a store, an event store and
2526
// an authorizer.
26-
func NewEntityClient(store store.EntityStore, storev2 storev2.Interface, eventStore store.EventStore, auth authorization.Authorizer) *EntityClient {
27+
func NewEntityClient(entityStore store.EntityStore, storev2 storev2.Interface, eventStore store.EventStore, auth authorization.Authorizer) *EntityClient {
28+
// Try to get SilencedStore from the entityStore if it implements the full Store interface
29+
var silencedStore store.Store
30+
if s, ok := entityStore.(store.Store); ok {
31+
silencedStore = s
32+
}
33+
2734
return &EntityClient{
28-
storev2: storev2,
29-
entityStore: store,
30-
eventStore: eventStore,
31-
auth: auth,
35+
storev2: storev2,
36+
entityStore: entityStore,
37+
eventStore: eventStore,
38+
silencedStore: silencedStore,
39+
auth: auth,
3240
}
3341
}
3442

@@ -64,6 +72,39 @@ func (e *EntityClient) DeleteEntity(ctx context.Context, name string) error {
6472
}
6573
}
6674

75+
// Delete entity-specific silenced entries (e.g., entity:web-01:*)
76+
if e.silencedStore != nil {
77+
entitySubscription := fmt.Sprintf("entity:%s", name)
78+
silencedEntries, err := e.silencedStore.GetSilencedEntriesBySubscription(ctx, entitySubscription)
79+
if err != nil {
80+
// Log the error but continue
81+
logger.WithError(err).WithFields(logrus.Fields{
82+
"entity": name,
83+
"subscription": entitySubscription,
84+
}).Warn("error fetching silenced entries for entity")
85+
} else if len(silencedEntries) > 0 {
86+
silencedNames := make([]string, 0, len(silencedEntries))
87+
for _, entry := range silencedEntries {
88+
silencedNames = append(silencedNames, entry.Name)
89+
}
90+
91+
err = e.silencedStore.DeleteSilencedEntryByName(ctx, silencedNames...)
92+
if err != nil {
93+
// Log the error but continue
94+
logger.WithError(err).WithFields(logrus.Fields{
95+
"entity": name,
96+
"silences": silencedNames,
97+
}).Warn("error deleting silenced entries for entity")
98+
} else {
99+
logger.WithFields(logrus.Fields{
100+
"entity": name,
101+
"silences": silencedNames,
102+
"count": len(silencedNames),
103+
}).Info("deleted entity-specific silenced entries")
104+
}
105+
}
106+
}
107+
67108
return nil
68109
}
69110

backend/api/entity_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,7 @@ func TestDeleteEntity(t *testing.T) {
703703
Store: func() store.Store {
704704
store := new(mockstore.MockStore)
705705
store.On("DeleteEntityByName", mock.Anything, "default").Return(nil)
706+
store.On("GetSilencedEntriesBySubscription", mock.Anything, []string{"entity:default"}).Return([]*corev2.Silenced{}, nil)
706707
return store
707708
},
708709
EventStore: func() store.EventStore {
@@ -736,6 +737,7 @@ func TestDeleteEntity(t *testing.T) {
736737
Store: func() store.Store {
737738
store := new(mockstore.MockStore)
738739
store.On("DeleteEntityByName", mock.Anything, "default").Return(nil)
740+
store.On("GetSilencedEntriesBySubscription", mock.Anything, []string{"entity:default"}).Return([]*corev2.Silenced{}, nil)
739741
return store
740742
},
741743
EventStore: func() store.EventStore {
@@ -770,6 +772,7 @@ func TestDeleteEntity(t *testing.T) {
770772
Store: func() store.Store {
771773
store := new(mockstore.MockStore)
772774
store.On("DeleteEntityByName", mock.Anything, "default").Return(nil)
775+
store.On("GetSilencedEntriesBySubscription", mock.Anything, []string{"entity:default"}).Return([]*corev2.Silenced{}, nil)
773776
return store
774777
},
775778
EventStore: func() store.EventStore {
@@ -804,6 +807,7 @@ func TestDeleteEntity(t *testing.T) {
804807
Store: func() store.Store {
805808
store := new(mockstore.MockStore)
806809
store.On("DeleteEntityByName", mock.Anything, "default").Return(nil)
810+
store.On("GetSilencedEntriesBySubscription", mock.Anything, []string{"entity:default"}).Return([]*corev2.Silenced{}, nil)
807811
return store
808812
},
809813
EventStore: func() store.EventStore {

backend/api/silenced_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ func TestGetSilencedByCheckName(t *testing.T) {
572572
},
573573
Store: func() store.Store {
574574
store := new(mockstore.MockStore)
575-
store.On("GetSilencedEntriesByCheckName", mock.Anything).Return([]*corev2.Silenced{defaultSilenced}, nil)
575+
store.On("GetSilencedEntriesByCheckName", mock.Anything, "default").Return([]*corev2.Silenced{defaultSilenced}, nil)
576576
return store
577577
},
578578
Auth: func() authorization.Authorizer {
@@ -694,7 +694,7 @@ func TestGetSilencedBySubscription(t *testing.T) {
694694
},
695695
Store: func() store.Store {
696696
store := new(mockstore.MockStore)
697-
store.On("GetSilencedEntriesBySubscription", mock.Anything).Return([]*corev2.Silenced{defaultSilenced}, nil)
697+
store.On("GetSilencedEntriesBySubscription", mock.Anything, []string{"default"}).Return([]*corev2.Silenced{defaultSilenced}, nil)
698698
return store
699699
},
700700
Auth: func() authorization.Authorizer {

backend/apid/actions/delete_events_by_entity.go

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ import (
1111
)
1212

1313
type EntityDeleter struct {
14-
EntityStore store.EntityStore
15-
EventStore store.EventStore
14+
EntityStore store.EntityStore
15+
EventStore store.EventStore
16+
SilencedStore store.SilencedStore
1617
}
1718

1819
func (d EntityDeleter) Delete(req *http.Request) (interface{}, error) {
@@ -22,6 +23,7 @@ func (d EntityDeleter) Delete(req *http.Request) (interface{}, error) {
2223
return nil, NewError(InvalidArgument, err)
2324
}
2425

26+
// Delete all events associated with the entity
2527
events, err := d.EventStore.GetEventsByEntity(req.Context(), entityName, &store.SelectionPredicate{})
2628
if err != nil {
2729
return nil, fmt.Errorf("error fetching events for entity: %s", err)
@@ -43,6 +45,40 @@ func (d EntityDeleter) Delete(req *http.Request) (interface{}, error) {
4345
}
4446
}
4547

48+
// Delete entity-specific silenced entries (e.g., entity:web-01:*)
49+
if d.SilencedStore != nil {
50+
entitySubscription := fmt.Sprintf("entity:%s", entityName)
51+
silencedEntries, err := d.SilencedStore.GetSilencedEntriesBySubscription(req.Context(), entitySubscription)
52+
if err != nil {
53+
// Log the error but continue with entity deletion
54+
logger.WithError(err).WithFields(logrus.Fields{
55+
"entity": entityName,
56+
"subscription": entitySubscription,
57+
}).Warn("error fetching silenced entries for entity")
58+
} else if len(silencedEntries) > 0 {
59+
silencedNames := make([]string, 0, len(silencedEntries))
60+
for _, entry := range silencedEntries {
61+
silencedNames = append(silencedNames, entry.Name)
62+
}
63+
64+
err = d.SilencedStore.DeleteSilencedEntryByName(req.Context(), silencedNames...)
65+
if err != nil {
66+
// Log the error but continue with entity deletion
67+
logger.WithError(err).WithFields(logrus.Fields{
68+
"entity": entityName,
69+
"silences": silencedNames,
70+
}).Warn("error deleting silenced entries for entity")
71+
} else {
72+
logger.WithFields(logrus.Fields{
73+
"entity": entityName,
74+
"silences": silencedNames,
75+
"count": len(silencedNames),
76+
}).Info("deleted entity-specific silenced entries")
77+
}
78+
}
79+
}
80+
81+
// Verify the entity exists before attempting deletion
4682
result, err := d.EntityStore.GetEntityByName(req.Context(), entityName)
4783
if err != nil {
4884
return nil, NewError(InternalErr, err)
@@ -52,5 +88,6 @@ func (d EntityDeleter) Delete(req *http.Request) (interface{}, error) {
5288
return nil, NewErrorf(NotFound)
5389
}
5490

91+
// Delete the entity
5592
return nil, d.EntityStore.DeleteEntityByName(req.Context(), entityName)
5693
}

backend/apid/actions/silenced.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ func (c SilencedController) List(ctx context.Context, sub, check string) ([]*cor
3636
if serr != nil {
3737
return nil, NewError(InternalErr, serr)
3838
}
39-
4039
return results, nil
4140
}
4241

backend/apid/actions/silenced_test.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,15 @@ func TestSilencedQuery(t *testing.T) {
9898
assert := assert.New(t)
9999

100100
// Mock store methods
101-
store.On("GetSilencedEntriesBySubscription", tc.ctx).Return(tc.storeRecords, tc.storeErr).Once()
102-
store.On("GetSilencedEntriesByCheckName", tc.ctx).Return(tc.storeRecords, tc.storeErr).Once()
103-
store.On("GetSilencedEntries", tc.ctx).Return(tc.storeRecords, tc.storeErr).Once()
101+
if tc.params["subscription"] != "" {
102+
store.On("GetSilencedEntriesBySubscription", tc.ctx, []string{tc.params["subscription"]}).Return(tc.storeRecords, tc.storeErr).Once()
103+
}
104+
if tc.params["check"] != "" {
105+
store.On("GetSilencedEntriesByCheckName", tc.ctx, tc.params["check"]).Return(tc.storeRecords, tc.storeErr).Once()
106+
}
107+
if tc.params["subscription"] == "" && tc.params["check"] == "" {
108+
store.On("GetSilencedEntries", tc.ctx).Return(tc.storeRecords, tc.storeErr).Once()
109+
}
104110

105111
// Exec Query
106112
results, err := actions.List(tc.ctx, tc.params["subscription"], tc.params["check"])

backend/apid/routers/entities.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ func (r *EntitiesRouter) Mount(parent *mux.Router) {
5858
}
5959

6060
deleter := actions.EntityDeleter{
61-
EntityStore: r.store,
62-
EventStore: r.eventStore,
61+
EntityStore: r.store,
62+
EventStore: r.eventStore,
63+
SilencedStore: r.store,
6364
}
6465

6566
routes.Del(deleter.Delete)

backend/apid/routers/entities_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ func TestEntitiesRouter(t *testing.T) {
4848
s.On("DeleteEventByEntityCheck", mock.Anything, "foo", "bar").Return(nil)
4949
s.On("DeleteEntityByName", mock.Anything, "foo").Return(nil)
5050
s.On("GetEntityByName", mock.Anything, "foo").Return(corev2.FixtureEntity("foo"), nil)
51+
s.On("GetSilencedEntriesBySubscription", mock.Anything, []string{"entity:foo"}).Return([]*corev2.Silenced{}, nil)
5152
s2 := new(storetest.Store)
5253
router := NewEntitiesRouter(s, s2, s)
5354
router.controller = controller

backend/store/etcd/silenced_store.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ func (s *Store) GetSilencedEntries(ctx context.Context) ([]*corev2.Silenced, err
8383
if err != nil {
8484
return nil, err
8585
}
86+
logger.Info("I am in listing")
8687
return silencedArray, nil
8788
}
8889

testing/mockstore/silenced.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ func (s *MockStore) GetSilencedEntriesByName(ctx context.Context, names ...strin
3131

3232
// GetSilencedEntriesBySubscription ...
3333
func (s *MockStore) GetSilencedEntriesBySubscription(ctx context.Context, subscriptions ...string) ([]*types.Silenced, error) {
34-
args := s.Called(ctx)
34+
args := s.Called(ctx, subscriptions)
3535
return args.Get(0).([]*types.Silenced), args.Error(1)
3636
}
3737

3838
// GetSilencedEntriesByCheckName ...
3939
func (s *MockStore) GetSilencedEntriesByCheckName(ctx context.Context, checkName string) ([]*types.Silenced, error) {
40-
args := s.Called(ctx)
40+
args := s.Called(ctx, checkName)
4141
return args.Get(0).([]*types.Silenced), args.Error(1)
4242
}
4343

0 commit comments

Comments
 (0)