Skip to content

Commit

Permalink
Added new cmd to remove triggers (#790)
Browse files Browse the repository at this point in the history
* feat(cli): Added new cmd

There is a problem - one of teams of Moira users have unused triggers. So it is a trash in database. Added command to remove triggers which have ID starting with prefix.

* refactor(cli): Renamed var

There was linter error and bug - shadow of global variable "triggers". Renamed global var for more detail because it has bigger scope that local var.
  • Loading branch information
Dimedrolity committed Oct 4, 2022
1 parent aff7e3e commit d33454b
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 11 deletions.
9 changes: 9 additions & 0 deletions cmd/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ var (
triggerDumpFile = flag.String("trigger-dump-file", "", "File that holds trigger dump JSON from api method response")
)

var removeTriggersStartWith = flag.String("remove-triggers-start-with", "", "Remove triggers which have ID starting with string parameter")

func main() { //nolint
confCleanup, logger, dataBase := initApp()

Expand Down Expand Up @@ -137,6 +139,13 @@ func main() { //nolint
log.Info("Removing all metrics finished")
}

if *removeTriggersStartWith != "" {
log := logger.String(moira.LogFieldNameContext, "remove-triggers-start-with")
if err := handleRemoveTriggersStartWith(logger, dataBase, *removeTriggersStartWith); err != nil {
log.Error(err)
}
}

if *cleanupUsers {
log := logger.String(moira.LogFieldNameContext, "cleanup-users")

Expand Down
34 changes: 34 additions & 0 deletions cmd/cli/triggers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package main

import (
"fmt"
"time"

"github.com/moira-alert/moira"
)

func handleRemoveTriggersStartWith(logger moira.Logger, database moira.Database, prefix string) error {
triggers, err := database.GetTriggerIDsStartWith(prefix)
if err != nil {
return fmt.Errorf("can't get trigger IDs start with prefix %s: %w", prefix, err)
}

// Added delay because command is potentially dangerous and can delete unwanted triggers
const delay = 10 * time.Second
logger.Infof("%d triggers start with %s would be removed after %s", len(triggers), prefix, delay)
logger.Info("You can cancel execution by Ctrl+C")
time.Sleep(delay)

logger.Infof("Removing triggers start with prefix %s has started", prefix)
for _, id := range triggers {
err := database.RemoveTrigger(id)
if err != nil {
return fmt.Errorf("can't remove trigger with id %s: %w", id, err)
}
}
logger.Infof("Removing triggers start with prefix %s has finished", prefix)
logger.Infof("Count of deleted is %d", len(triggers))
logger.Infof("Removed triggers: %s", triggers)

return nil
}
2 changes: 1 addition & 1 deletion database/redis/tag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestTagStoring(t *testing.T) {
client := *dataBase.client

Convey("Tags manipulation", t, func() {
trigger := triggers[0]
trigger := testTriggers[0]

Convey("Get tags when they don't exist", func() {
triggerIDs, err := dataBase.GetTagTriggerIDs(trigger.Tags[0])
Expand Down
18 changes: 18 additions & 0 deletions database/redis/trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package redis
import (
"fmt"
"strconv"
"strings"
"time"

"github.com/go-redis/redis/v8"
Expand Down Expand Up @@ -149,6 +150,23 @@ func (connector *DbConnector) SaveTrigger(triggerID string, trigger *moira.Trigg
return nil
}

// GetTriggerIDsStartWith returns triggers which have ID starting with "prefix" parameter.
func (connector *DbConnector) GetTriggerIDsStartWith(prefix string) ([]string, error) {
triggers, err := connector.GetAllTriggerIDs()
if err != nil {
return nil, err
}

var matchedTriggers []string
for _, id := range triggers {
if strings.HasPrefix(id, prefix) {
matchedTriggers = append(matchedTriggers, id)
}
}

return matchedTriggers, nil
}

func (connector *DbConnector) updateTrigger(triggerID string, newTrigger *moira.Trigger, oldTrigger *moira.Trigger) error {
bytes, err := reply.GetTriggerBytes(triggerID, newTrigger)
if err != nil {
Expand Down
64 changes: 54 additions & 10 deletions database/redis/trigger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestTriggerStoring(t *testing.T) {

Convey("Trigger manipulation", t, func() {
Convey("Test trigger has subscriptions with AnyTag is true", func() {
trigger := &triggers[0]
trigger := &testTriggers[0]
subscription := moira.SubscriptionData{
ID: "subscriptionID-00000000000001",
Enabled: true,
Expand All @@ -52,7 +52,7 @@ func TestTriggerStoring(t *testing.T) {
})

Convey("Test save-get-remove", func() {
trigger := &triggers[0]
trigger := &testTriggers[0]

//Check for not existing not written trigger
actual, err := dataBase.GetTrigger(trigger.ID)
Expand Down Expand Up @@ -99,7 +99,7 @@ func TestTriggerStoring(t *testing.T) {

//Now just add tag and pattern in trigger and save it
trigger = nil
changedTrigger := &triggers[1]
changedTrigger := &testTriggers[1]
err = dataBase.SaveTrigger(changedTrigger.ID, changedTrigger)
So(err, ShouldBeNil)

Expand Down Expand Up @@ -139,7 +139,7 @@ func TestTriggerStoring(t *testing.T) {
oldTag := changedTrigger.Tags[1]
oldPattern := changedTrigger.Patterns[1]
changedTrigger = nil
changedAgainTrigger := &triggers[2]
changedAgainTrigger := &testTriggers[2]
err = dataBase.SaveTrigger(changedAgainTrigger.ID, changedAgainTrigger)
So(err, ShouldBeNil)

Expand Down Expand Up @@ -228,7 +228,7 @@ func TestTriggerStoring(t *testing.T) {
})

Convey("Save trigger with lastCheck and throttling and GetTriggerChecks", func() {
trigger := triggers[5]
trigger := testTriggers[5]
triggerCheck := &moira.TriggerCheck{
Trigger: trigger,
LastCheck: moira.CheckData{},
Expand Down Expand Up @@ -473,7 +473,7 @@ func TestTriggerStoring(t *testing.T) {

Convey("Test trigger manipulations update 'triggers to reindex' list", func() {
dataBase.Flush()
trigger := &triggers[0]
trigger := &testTriggers[0]

err := dataBase.SaveTrigger(trigger.ID, trigger)
So(err, ShouldBeNil)
Expand All @@ -487,7 +487,7 @@ func TestTriggerStoring(t *testing.T) {
So(actual, ShouldResemble, []string{trigger.ID})

// Now update trigger
trigger = &triggers[1]
trigger = &testTriggers[1]

err = dataBase.SaveTrigger(trigger.ID, trigger)
So(err, ShouldBeNil)
Expand All @@ -497,7 +497,7 @@ func TestTriggerStoring(t *testing.T) {
So(actual, ShouldResemble, []string{trigger.ID})

// Add new trigger
trigger = &triggers[5]
trigger = &testTriggers[5]

err = dataBase.SaveTrigger(trigger.ID, trigger)
So(err, ShouldBeNil)
Expand Down Expand Up @@ -699,7 +699,7 @@ func TestTriggerErrorConnection(t *testing.T) {
So(err, ShouldNotBeNil)
So(actual2, ShouldBeNil)

err = dataBase.SaveTrigger("", &triggers[0])
err = dataBase.SaveTrigger("", &testTriggers[0])
So(err, ShouldNotBeNil)

err = dataBase.RemoveTrigger("")
Expand Down Expand Up @@ -765,7 +765,51 @@ func TestDbConnector_preSaveTrigger(t *testing.T) {
})
}

var triggers = []moira.Trigger{
func TestDbConnector_GetTriggerIDsStartWith(t *testing.T) {
logger, _ := logging.ConfigureLog("stdout", "info", "test", true)
db := NewTestDatabase(logger)
db.Flush()
defer db.Flush()

Convey("Given 3 triggers in DB", t, func() {
const prefix = "prefix"
var triggerWithPrefix1 = moira.Trigger{
ID: prefix + "1",
}
var triggerWithPrefix2 = moira.Trigger{
ID: prefix + "2",
}
var triggerWithoutPrefix = moira.Trigger{
ID: "without-prefix",
}
var triggers = []moira.Trigger{
triggerWithPrefix1,
triggerWithPrefix2,
triggerWithoutPrefix,
}

for _, trigger := range triggers {
err := db.SaveTrigger(trigger.ID, &trigger)
So(err, ShouldBeNil)
}

Convey("When GetTriggerIDsStartWith was called", func() {
matchedTriggers, err := db.GetTriggerIDsStartWith(prefix)

Convey("Returned triggers should resemble triggers with prefix", func() {
So(err, ShouldBeNil)
expected := []string{triggerWithPrefix1.ID, triggerWithPrefix2.ID}

So(matchedTriggers, ShouldHaveLength, len(expected))
for _, trigger := range expected {
So(matchedTriggers, ShouldContain, trigger)
}
})
})
})
}

var testTriggers = []moira.Trigger{
{
ID: "triggerID-0000000000001",
Name: "test trigger 1 v1.0",
Expand Down
1 change: 1 addition & 0 deletions interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type Database interface {
RemoveTrigger(triggerID string) error
GetPatternTriggerIDs(pattern string) ([]string, error)
RemovePatternTriggerIDs(pattern string) error
GetTriggerIDsStartWith(prefix string) ([]string, error)

// SearchResult AKA pager storing
GetTriggersSearchResults(searchResultsID string, page, size int64) ([]*SearchResult, int64, error)
Expand Down
15 changes: 15 additions & 0 deletions mock/moira-alert/database.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d33454b

Please sign in to comment.