Alerting: Provisioning to fix contact point type on save (#112246)
fix contact point type on create\update
This commit is contained in:
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
)
|
||||
|
||||
func EmbeddedContactPointToGrafanaIntegrationConfig(e definitions.EmbeddedContactPoint) (alertingModels.IntegrationConfig, error) {
|
||||
func EmbeddedContactPointToGrafanaIntegrationConfig(e *definitions.EmbeddedContactPoint) (alertingModels.IntegrationConfig, error) {
|
||||
data, err := e.Settings.MarshalJSON()
|
||||
if err != nil {
|
||||
return alertingModels.IntegrationConfig{}, err
|
||||
|
||||
@@ -151,7 +151,7 @@ func (ecp *ContactPointService) CreateContactPoint(
|
||||
contactPoint apimodels.EmbeddedContactPoint,
|
||||
provenance models.Provenance,
|
||||
) (apimodels.EmbeddedContactPoint, error) {
|
||||
if err := ValidateContactPoint(ctx, contactPoint, ecp.encryptionService.GetDecryptedValue); err != nil {
|
||||
if err := ValidateContactPoint(ctx, &contactPoint, ecp.encryptionService.GetDecryptedValue); err != nil {
|
||||
return apimodels.EmbeddedContactPoint{}, fmt.Errorf("%w: %s", ErrValidation, err.Error())
|
||||
}
|
||||
|
||||
@@ -243,14 +243,20 @@ func (ecp *ContactPointService) UpdateContactPoint(ctx context.Context, orgID in
|
||||
if contactPoint.Settings == nil {
|
||||
return fmt.Errorf("%w: %s", ErrValidation, "settings should not be empty")
|
||||
}
|
||||
iType, err := alertingNotify.IntegrationTypeFromString(contactPoint.Type)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %s", ErrValidation, err.Error())
|
||||
}
|
||||
typeSchema, ok := alertingNotify.GetSchemaVersionForIntegration(iType, schema.V1)
|
||||
if !ok {
|
||||
return fmt.Errorf("%w: failed to get secret keys for contact point type %s", ErrValidation, contactPoint.Type)
|
||||
}
|
||||
|
||||
// patch integration with the secrets from the existing version
|
||||
rawContactPoint, err := ecp.getContactPointDecrypted(ctx, orgID, contactPoint.UID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
typeSchema, ok := alertingNotify.GetSchemaVersionForIntegration(schema.IntegrationType(contactPoint.Type), schema.V1)
|
||||
if !ok {
|
||||
return fmt.Errorf("%w: failed to get secret keys for contact point type %s", ErrValidation, contactPoint.Type)
|
||||
}
|
||||
for _, secretPath := range typeSchema.GetSecretFieldsPaths() {
|
||||
secretKey := secretPath.String()
|
||||
secretValue := contactPoint.Settings.Get(secretKey).MustString()
|
||||
@@ -260,7 +266,7 @@ func (ecp *ContactPointService) UpdateContactPoint(ctx context.Context, orgID in
|
||||
}
|
||||
|
||||
// validate merged values
|
||||
if err := ValidateContactPoint(ctx, contactPoint, ecp.encryptionService.GetDecryptedValue); err != nil {
|
||||
if err := ValidateContactPoint(ctx, &contactPoint, ecp.encryptionService.GetDecryptedValue); err != nil {
|
||||
return fmt.Errorf("%w: %s", ErrValidation, err.Error())
|
||||
}
|
||||
|
||||
@@ -512,7 +518,12 @@ groupLoop:
|
||||
return oldReceiverName, fullRemoval, newReceiverCreated
|
||||
}
|
||||
|
||||
func ValidateContactPoint(ctx context.Context, e apimodels.EmbeddedContactPoint, decryptFunc alertingNotify.GetDecryptedValueFn) error {
|
||||
func ValidateContactPoint(ctx context.Context, e *apimodels.EmbeddedContactPoint, decryptFunc alertingNotify.GetDecryptedValueFn) error {
|
||||
iType, err := alertingNotify.IntegrationTypeFromString(e.Type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.Type = string(iType)
|
||||
integration, err := EmbeddedContactPointToGrafanaIntegrationConfig(e)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/grafana/alerting/notify"
|
||||
"github.com/grafana/alerting/notify/notifytest"
|
||||
"github.com/grafana/alerting/receivers/schema"
|
||||
"github.com/grafana/alerting/receivers/slack"
|
||||
"github.com/prometheus/alertmanager/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -146,6 +147,21 @@ func TestIntegrationContactPointService(t *testing.T) {
|
||||
require.ErrorIs(t, err, ErrValidation)
|
||||
})
|
||||
|
||||
t.Run("create accepts contact point with type in different cases", func(t *testing.T) {
|
||||
sut := createContactPointServiceSut(t, secretsService)
|
||||
newCp := createTestContactPoint()
|
||||
newCp.Type = "Slack"
|
||||
|
||||
created, err := sut.CreateContactPoint(context.Background(), 1, redactedUser, newCp, models.ProvenanceAPI)
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, slack.Type, created.Type)
|
||||
|
||||
got, err := sut.GetContactPoints(context.Background(), cpsQueryWithName(1, newCp.Name), redactedUser)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, got, 1)
|
||||
assert.EqualValues(t, slack.Type, got[0].Type)
|
||||
})
|
||||
|
||||
t.Run("update rejects contact points with no settings", func(t *testing.T) {
|
||||
sut := createContactPointServiceSut(t, secretsService)
|
||||
newCp := createTestContactPoint()
|
||||
@@ -182,6 +198,22 @@ func TestIntegrationContactPointService(t *testing.T) {
|
||||
require.ErrorIs(t, err, ErrValidation)
|
||||
})
|
||||
|
||||
t.Run("update accepts contact points with type in another case", func(t *testing.T) {
|
||||
sut := createContactPointServiceSut(t, secretsService)
|
||||
newCp := createTestContactPoint()
|
||||
newCp, err := sut.CreateContactPoint(context.Background(), 1, redactedUser, newCp, models.ProvenanceAPI)
|
||||
require.NoError(t, err)
|
||||
newCp.Type = "Slack"
|
||||
|
||||
err = sut.UpdateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI)
|
||||
require.NoError(t, err)
|
||||
|
||||
got, err := sut.GetContactPoints(context.Background(), cpsQueryWithName(1, newCp.Name), redactedUser)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, got, 1)
|
||||
assert.EqualValues(t, slack.Type, got[0].Type)
|
||||
})
|
||||
|
||||
t.Run("update renames references when group is renamed", func(t *testing.T) {
|
||||
cfg := createEncryptedConfig(t, secretsService)
|
||||
store := fakes.NewFakeAlertmanagerConfigStore(cfg)
|
||||
|
||||
@@ -95,7 +95,7 @@ func (config *ReceiverV1) mapToModel(name string) (definitions.EmbeddedContactPo
|
||||
}
|
||||
// As the values are not encrypted when coming from disk files,
|
||||
// we can simply return the fallback for validation.
|
||||
err := provisioning.ValidateContactPoint(context.Background(), cp, func(_ context.Context, _ map[string][]byte, _, fallback string) string {
|
||||
err := provisioning.ValidateContactPoint(context.Background(), &cp, func(_ context.Context, _ map[string][]byte, _, fallback string) string {
|
||||
return fallback
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user