Skip to content

Commit

Permalink
Feature: Support group topics in Telgram sender (#1022)
Browse files Browse the repository at this point in the history
Authored by: @Gaspero
  • Loading branch information
Gaspero authored Jun 27, 2024
1 parent 4a2b7a5 commit 736382c
Show file tree
Hide file tree
Showing 13 changed files with 812 additions and 108 deletions.
29 changes: 29 additions & 0 deletions cmd/cli/from_2.11_to_2.12.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

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

func updateFrom211(logger moira.Logger, database moira.Database) error {
logger.Info().Msg("Update 2.11 -> 2.12 was started")

err := updateTelegramUsersRecords(logger, database)
if err != nil {
return err
}

logger.Info().Msg("Update 2.11 -> 2.12 was finished")
return nil
}

func downgradeTo211(logger moira.Logger, database moira.Database) error {
logger.Info().Msg("Downgrade 2.12 -> 2.11 started")

err := downgradeTelegramUsersRecords(logger, database)
if err != nil {
return err
}

logger.Info().Msg("Downgrade 2.12 -> 2.11 was finished")
return nil
}
16 changes: 15 additions & 1 deletion cmd/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ var (
GoVersion = "unknown"
)

var moiraValidVersions = []string{"2.3", "2.6", "2.7", "2.9"}
var moiraValidVersions = []string{"2.3", "2.6", "2.7", "2.9", "2.11"}

var (
configFileName = flag.String("config", "/etc/moira/cli.yml", "Path to configuration file")
Expand Down Expand Up @@ -110,6 +110,13 @@ func main() { //nolint
Error(err).
Msg("Fail to update from version 2.9")
}
case "2.11":
err := updateFrom211(logger, database)
if err != nil {
logger.Fatal().
Error(err).
Msg("Fail to update from version 2.11")
}
}
}

Expand Down Expand Up @@ -144,6 +151,13 @@ func main() { //nolint
Error(err).
Msg("Fail to update to version 2.9")
}
case "2.11":
err := downgradeTo211(logger, database)
if err != nil {
logger.Fatal().
Error(err).
Msg("Fail to update to version 2.11")
}
}
}

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

import (
"encoding/json"
"fmt"
"strconv"
"strings"

"github.com/moira-alert/moira"
"github.com/moira-alert/moira/database/redis"
"github.com/moira-alert/moira/senders/telegram"
)

var (
telegramUsersKey = "moira-telegram-users:"
telegramLockName = "moira-telegram-users:moira-bot-host:"
)

func updateTelegramUsersRecords(logger moira.Logger, database moira.Database) error {
logger.Info().Msg("Start updateTelegramUsersRecords")

switch d := database.(type) {
case *redis.DbConnector:
pipe := d.Client().TxPipeline()
iter := d.Client().Scan(d.Context(), 0, telegramUsersKey+"*", 0).Iterator()
for iter.Next(d.Context()) {
key := iter.Val()
if strings.HasPrefix(key, telegramLockName) {
continue
}

oldValue, err := d.Client().Get(d.Context(), key).Result()
if err != nil {
return err
}

var chatID int64
var chat *telegram.Chat
var chatBytes []byte

chatID, err = strconv.ParseInt(oldValue, 10, 64)
if err != nil {
return err
}

if chatID < 0 {
chat = &telegram.Chat{
Type: "group",
ID: chatID,
}
} else {
chat = &telegram.Chat{
Type: "private",
ID: chatID,
}
}

chatBytes, err = json.Marshal(chat)
if err != nil {
return err
}

pipe.Set(d.Context(), key, string(chatBytes), 0)
}
_, err := pipe.Exec(d.Context())
if err != nil {
return err
}
default:
return makeUnknownDBError(database)
}

logger.Info().Msg("Successfully finished updateTelegramUsersRecords")

return nil
}

func downgradeTelegramUsersRecords(logger moira.Logger, database moira.Database) error {
logger.Info().Msg("Start downgradeTelegramUsersValue")

switch d := database.(type) {
case *redis.DbConnector:
pipe := d.Client().TxPipeline()
iter := d.Client().Scan(d.Context(), 0, telegramUsersKey+"*", 0).Iterator()
for iter.Next(d.Context()) {
key := iter.Val()
if strings.HasPrefix(key, telegramLockName) {
continue
}

oldValue, err := d.Client().Get(d.Context(), key).Result()
if err != nil {
return err
}

var newValue string

chat := telegram.Chat{}
err = json.Unmarshal([]byte(oldValue), &chat)
if err != nil {
return err
}

if chat.ID == 0 {
return fmt.Errorf("chat ID is null")
} else {
newValue = strconv.FormatInt(chat.ID, 10)
}
pipe.Set(d.Context(), key, newValue, 0)
}
_, err := pipe.Exec(d.Context())
if err != nil {
return err
}
default:
return makeUnknownDBError(database)
}

logger.Info().Msg("Successfully finished downgradeTelegramUsersValue")

return nil
}
123 changes: 123 additions & 0 deletions cmd/cli/telegram_utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package main

import (
"testing"

"github.com/moira-alert/moira"
"github.com/moira-alert/moira/database/redis"
logging "github.com/moira-alert/moira/logging/zerolog_adapter"

. "github.com/smartystreets/goconvey/convey"
)

func TestUpdateTelegramUsersRecords(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}

conf := getDefault()
logger, err := logging.ConfigureLog(conf.LogFile, "error", "cli", conf.LogPrettyFormat)
if err != nil {
t.Fatal(err)
}

database := redis.NewTestDatabase(logger)
database.Flush()
defer database.Flush()
client := database.Client()
ctx := database.Context()

Convey("Test data migration forwards", t, func() {
Convey("Given old database", func() {
createOldTelegramUserRecords(database)

Convey("When migration was applied", func() {
err := updateTelegramUsersRecords(logger, database)
So(err, ShouldBeNil)

Convey("Database should be new", func() {
result, err := client.Get(ctx, "moira-telegram-users:some telegram group").Result()
So(err, ShouldBeNil)
So(result, ShouldEqual, "{\"chatId\":-1001494975744,\"type\":\"group\"}")

result, err = client.Get(ctx, "moira-telegram-users:@durov").Result()
So(err, ShouldBeNil)
So(result, ShouldEqual, "{\"chatId\":1,\"type\":\"private\"}")

result, err = client.Get(ctx, "moira-telegram-users:moira-bot-host").Result()
So(err, ShouldBeNil)
So(result, ShouldEqual, "D4VdnzZDTS/xXF87THARWw==")
})
})
})
})
}

func TestDowngradeTelegramUsersRecords(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}

conf := getDefault()
logger, err := logging.ConfigureLog(conf.LogFile, "error", "cli", conf.LogPrettyFormat)
if err != nil {
t.Fatal(err)
}

database := redis.NewTestDatabase(logger)
database.Flush()
defer database.Flush()
client := database.Client()
ctx := database.Context()

Convey("Test data migration backwards", t, func() {
Convey("Given new database", func() {
createNewTelegramUserRecords(database)

Convey("When migration was applied", func() {
err := downgradeTelegramUsersRecords(logger, database)
So(err, ShouldBeNil)

Convey("Database should be old", func() {
result, err := client.Get(ctx, "moira-telegram-users:some telegram group").Result()
So(err, ShouldBeNil)
So(result, ShouldEqual, "-1001494975744")

result, err = client.Get(ctx, "moira-telegram-users:@durov").Result()
So(err, ShouldBeNil)
So(result, ShouldEqual, "1")

result, err = client.Get(ctx, "moira-telegram-users:moira-bot-host").Result()
So(err, ShouldBeNil)
So(result, ShouldEqual, "D4VdnzZDTS/xXF87THARWw==")
})
})
})
})
}

func createOldTelegramUserRecords(database moira.Database) {
switch d := database.(type) {
case *redis.DbConnector:
d.Flush()
client := d.Client()
ctx := d.Context()

client.Set(ctx, "moira-telegram-users:some telegram group", "-1001494975744", -1)
client.Set(ctx, "moira-telegram-users:@durov", "1", -1)
client.Set(ctx, "moira-telegram-users:moira-bot-host", "D4VdnzZDTS/xXF87THARWw==", -1)
}
}

func createNewTelegramUserRecords(database moira.Database) {
switch d := database.(type) {
case *redis.DbConnector:
d.Flush()
client := d.Client()
ctx := d.Context()

client.Set(ctx, "moira-telegram-users:some telegram group", "{\"type\":\"group\",\"chatId\":-1001494975744}", -1)
client.Set(ctx, "moira-telegram-users:@durov", "{\"type\":\"private\",\"chatId\":1}", -1)
client.Set(ctx, "moira-telegram-users:moira-bot-host", "D4VdnzZDTS/xXF87THARWw==", -1)
}
}
1 change: 1 addition & 0 deletions generate_mocks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ mockgen -destination=mock/moira-alert/metrics/meter.go -package=mock_moira_alert
mockgen -destination=mock/moira-alert/prometheus_api.go -package=mock_moira_alert github.com/moira-alert/moira/metric_source/prometheus PrometheusApi

mockgen -destination=mock/moira-alert/database_stats.go -package=mock_moira_alert github.com/moira-alert/moira/database/stats StatsReporter
mockgen -destination=mock/notifier/telegram/bot.go -package=mock_telegram github.com/moira-alert/moira/senders/telegram Bot

git add mock/*
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ require (
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/h2non/gock.v1 v1.1.2
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637
gopkg.in/tucnak/telebot.v2 v2.5.0
gopkg.in/yaml.v2 v2.4.0
)

Expand All @@ -53,6 +52,7 @@ require (
github.com/mitchellh/mapstructure v1.5.0
github.com/moira-alert/blackfriday-slack v0.1.2
github.com/swaggo/http-swagger v1.3.4
gopkg.in/telebot.v3 v3.2.1
)

require (
Expand Down
Loading

0 comments on commit 736382c

Please sign in to comment.