CloudMigrations: create snapshot for Contact Points (#94719)
* CloudMigrations: create snapshot for Contact Points * CloudMigrations: add contact point copies and components in frontend * CloudMigrations: temporarily use bell for all alerts resources
This commit is contained in:
@@ -783,7 +783,7 @@ func setUpServiceTest(t *testing.T, withDashboardMock bool) cloudmigration.Servi
|
||||
kvStore := kvstore.ProvideService(sqlStore)
|
||||
|
||||
bus := bus.ProvideBus(tracer)
|
||||
fakeAccessControl := actest.FakeAccessControl{}
|
||||
fakeAccessControl := actest.FakeAccessControl{ExpectedEvaluate: true}
|
||||
fakeAccessControlService := actest.FakeService{}
|
||||
alertMetrics := metrics.NewNGAlert(prometheus.NewRegistry())
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ var currentMigrationTypes = []cloudmigration.MigrateDataType{
|
||||
cloudmigration.DashboardDataType,
|
||||
cloudmigration.MuteTimingType,
|
||||
cloudmigration.NotificationTemplateType,
|
||||
cloudmigration.ContactPointType,
|
||||
}
|
||||
|
||||
func (s *Service) getMigrationDataJSON(ctx context.Context, signedInUser *user.SignedInUser) (*cloudmigration.MigrateDataRequest, error) {
|
||||
@@ -74,10 +75,17 @@ func (s *Service) getMigrationDataJSON(ctx context.Context, signedInUser *user.S
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Alerts: Contact Points
|
||||
contactPoints, err := s.getContactPoints(ctx, signedInUser)
|
||||
if err != nil {
|
||||
s.log.Error("Failed to get alert contact points", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
migrationDataSlice := make(
|
||||
[]cloudmigration.MigrateDataRequestItem, 0,
|
||||
len(dataSources)+len(dashs)+len(folders)+len(libraryElements)+
|
||||
len(muteTimings)+len(notificationTemplates),
|
||||
len(muteTimings)+len(notificationTemplates)+len(contactPoints),
|
||||
)
|
||||
|
||||
for _, ds := range dataSources {
|
||||
@@ -142,6 +150,15 @@ func (s *Service) getMigrationDataJSON(ctx context.Context, signedInUser *user.S
|
||||
})
|
||||
}
|
||||
|
||||
for _, contactPoint := range contactPoints {
|
||||
migrationDataSlice = append(migrationDataSlice, cloudmigration.MigrateDataRequestItem{
|
||||
Type: cloudmigration.ContactPointType,
|
||||
RefID: contactPoint.UID,
|
||||
Name: contactPoint.Name,
|
||||
Data: contactPoint,
|
||||
})
|
||||
}
|
||||
|
||||
// Obtain the names of parent elements for Dashboard and Folders data types
|
||||
parentNamesByType, err := s.getParentNames(ctx, signedInUser, dashs, folders, libraryElements)
|
||||
if err != nil {
|
||||
|
||||
@@ -6,7 +6,9 @@ import (
|
||||
|
||||
"github.com/prometheus/alertmanager/config"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
)
|
||||
|
||||
@@ -66,3 +68,41 @@ func (s *Service) getNotificationTemplates(ctx context.Context, signedInUser *us
|
||||
|
||||
return notificationTemplates, nil
|
||||
}
|
||||
|
||||
type contactPoint struct {
|
||||
Settings *simplejson.Json `json:"settings"`
|
||||
UID string `json:"uid"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
DisableResolveMessage bool `json:"disableResolveMessage"`
|
||||
}
|
||||
|
||||
func (s *Service) getContactPoints(ctx context.Context, signedInUser *user.SignedInUser) ([]contactPoint, error) {
|
||||
if !s.features.IsEnabledGlobally(featuremgmt.FlagOnPremToCloudMigrationsAlerts) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
query := provisioning.ContactPointQuery{
|
||||
OrgID: signedInUser.GetOrgID(),
|
||||
Decrypt: true, // needed to recreate the settings in the target instance.
|
||||
}
|
||||
|
||||
embeddedContactPoints, err := s.ngAlert.Api.ContactPointService.GetContactPoints(ctx, query, signedInUser)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fetching ngalert contact points: %w", err)
|
||||
}
|
||||
|
||||
contactPoints := make([]contactPoint, 0, len(embeddedContactPoints))
|
||||
|
||||
for _, embeddedContactPoint := range embeddedContactPoints {
|
||||
contactPoints = append(contactPoints, contactPoint{
|
||||
UID: embeddedContactPoint.UID,
|
||||
Name: embeddedContactPoint.Name,
|
||||
Type: embeddedContactPoint.Type,
|
||||
Settings: embeddedContactPoint.Settings,
|
||||
DisableResolveMessage: embeddedContactPoint.DisableResolveMessage,
|
||||
})
|
||||
}
|
||||
|
||||
return contactPoints, nil
|
||||
}
|
||||
|
||||
@@ -7,7 +7,10 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
ac "github.com/grafana/grafana/pkg/services/ngalert/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
)
|
||||
@@ -72,6 +75,44 @@ func TestGetNotificationTemplates(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetContactPoints(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
t.Cleanup(cancel)
|
||||
|
||||
t.Run("when the feature flag `onPremToCloudMigrationsAlerts` is not enabled it returns nil", func(t *testing.T) {
|
||||
s := setUpServiceTest(t, false).(*Service)
|
||||
s.features = featuremgmt.WithFeatures(featuremgmt.FlagOnPremToCloudMigrations)
|
||||
|
||||
contactPoints, err := s.getContactPoints(ctx, nil)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, contactPoints)
|
||||
})
|
||||
|
||||
t.Run("when the feature flag `onPremToCloudMigrationsAlerts` is enabled it returns the contact points", func(t *testing.T) {
|
||||
s := setUpServiceTest(t, false).(*Service)
|
||||
s.features = featuremgmt.WithFeatures(featuremgmt.FlagOnPremToCloudMigrations, featuremgmt.FlagOnPremToCloudMigrationsAlerts)
|
||||
|
||||
user := &user.SignedInUser{
|
||||
OrgID: 1,
|
||||
Permissions: map[int64]map[string][]string{
|
||||
1: {
|
||||
accesscontrol.ActionAlertingNotificationsRead: nil,
|
||||
accesscontrol.ActionAlertingReceiversReadSecrets: {ac.ScopeReceiversAll},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
defaultEmailContactPointCount := 1
|
||||
|
||||
createdContactPoints := createContactPoints(t, ctx, s, user)
|
||||
|
||||
contactPoints, err := s.getContactPoints(ctx, user)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, contactPoints)
|
||||
require.Len(t, contactPoints, len(createdContactPoints)+defaultEmailContactPointCount)
|
||||
})
|
||||
}
|
||||
|
||||
func createMuteTiming(t *testing.T, ctx context.Context, service *Service, orgID int64) definitions.MuteTimeInterval {
|
||||
t.Helper()
|
||||
|
||||
@@ -99,6 +140,8 @@ func createMuteTiming(t *testing.T, ctx context.Context, service *Service, orgID
|
||||
}
|
||||
|
||||
func createNotificationTemplate(t *testing.T, ctx context.Context, service *Service, orgID int64) definitions.NotificationTemplate {
|
||||
t.Helper()
|
||||
|
||||
tmpl := definitions.NotificationTemplate{
|
||||
Name: "MyTestNotificationTemplate",
|
||||
Template: "This is a test template\n{{ .ExternalURL }}",
|
||||
@@ -109,3 +152,56 @@ func createNotificationTemplate(t *testing.T, ctx context.Context, service *Serv
|
||||
|
||||
return createdTemplate
|
||||
}
|
||||
|
||||
func createContactPoints(t *testing.T, ctx context.Context, service *Service, user *user.SignedInUser) []definitions.EmbeddedContactPoint {
|
||||
t.Helper()
|
||||
|
||||
slackSettings, err := simplejson.NewJson([]byte(`{
|
||||
"icon_emoji":"iconemoji",
|
||||
"icon_url":"iconurl",
|
||||
"recipient":"recipient",
|
||||
"token":"slack-secret",
|
||||
"username":"user"
|
||||
}`))
|
||||
require.NoError(t, err)
|
||||
|
||||
telegramSettings, err := simplejson.NewJson([]byte(`{
|
||||
"bottoken":"telegram-secret",
|
||||
"chatid":"chat-id",
|
||||
"disable_notification":true,
|
||||
"disable_web_page_preview":false,
|
||||
"message_thread_id":"1234",
|
||||
"parse_mode":"None",
|
||||
"protect_content":true
|
||||
}`))
|
||||
require.NoError(t, err)
|
||||
|
||||
nameGroup := "group_1"
|
||||
|
||||
slackContactPoint := definitions.EmbeddedContactPoint{
|
||||
Name: nameGroup,
|
||||
Type: "slack",
|
||||
Settings: slackSettings,
|
||||
DisableResolveMessage: false,
|
||||
Provenance: "",
|
||||
}
|
||||
|
||||
createdSlack, err := service.ngAlert.Api.ContactPointService.CreateContactPoint(ctx, user.GetOrgID(), user, slackContactPoint, "")
|
||||
require.NoError(t, err)
|
||||
|
||||
telegramContactPoint := definitions.EmbeddedContactPoint{
|
||||
Name: nameGroup,
|
||||
Type: "telegram",
|
||||
Settings: telegramSettings,
|
||||
DisableResolveMessage: false,
|
||||
Provenance: "",
|
||||
}
|
||||
|
||||
createdTelegram, err := service.ngAlert.Api.ContactPointService.CreateContactPoint(ctx, user.GetOrgID(), user, telegramContactPoint, "")
|
||||
require.NoError(t, err)
|
||||
|
||||
return []definitions.EmbeddedContactPoint{
|
||||
createdSlack,
|
||||
createdTelegram,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user