grafana/pkg/tests/api/alerting/api_remote_alertmanager_test.go
Yuri Tseretyan e200f78541
Some checks are pending
Actionlint / Lint GitHub Actions files (push) Waiting to run
Backend Code Checks / Detect whether code changed (push) Waiting to run
Backend Code Checks / Validate Backend Configs (push) Blocked by required conditions
Backend Unit Tests / Detect whether code changed (push) Waiting to run
Backend Unit Tests / Grafana (1/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (2/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (3/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (4/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (5/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (6/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (7/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (8/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (1/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (2/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (3/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (4/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (5/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (6/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (7/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (8/8) (push) Blocked by required conditions
Backend Unit Tests / All backend unit tests complete (push) Blocked by required conditions
Build Go (matrix) / darwin/amd64 (push) Waiting to run
Build Go (matrix) / linux/amd64 (push) Waiting to run
Build Go (matrix) / linux/armv6 (push) Waiting to run
Build Go (matrix) / linux/armv7 (push) Waiting to run
Build Go (matrix) / darwin/arm64 (push) Waiting to run
Build Go (matrix) / linux/arm64 (push) Waiting to run
Build Go (matrix) / windows/arm64 (push) Waiting to run
Build Go (matrix) / linux/s390x (push) Waiting to run
Build Go (matrix) / darwin/amd64 (enterprise) (push) Waiting to run
Build Go (matrix) / linux/amd64 (enterprise) (push) Waiting to run
Build Go (matrix) / linux/armv6 (enterprise) (push) Waiting to run
Build Go (matrix) / linux/armv7 (enterprise) (push) Waiting to run
Build Go (matrix) / darwin/arm64 (enterprise) (push) Waiting to run
Build Go (matrix) / linux/arm64 (enterprise) (push) Waiting to run
Build Go (matrix) / windows/arm64 (enterprise) (push) Waiting to run
Build Go (matrix) / linux/s390x (enterprise) (push) Waiting to run
Build Go (matrix) / verify rpm stig (linux/amd64) (push) Waiting to run
Lint Frontend / Detect whether code changed (push) Waiting to run
Lint Frontend / Lint (push) Blocked by required conditions
Lint Frontend / Typecheck (push) Blocked by required conditions
Lint Frontend / Typecheck (TSGO/TS7) (push) Blocked by required conditions
Lint Frontend / Verify API clients (push) Waiting to run
Lint Frontend / Verify OpenAPI specs (push) Waiting to run
Lint Frontend / Verify API clients (enterprise) (push) Waiting to run
Lint Frontend / Verify packed frontend packages (push) Blocked by required conditions
Lint Frontend / Check circular dependencies (push) Blocked by required conditions
Lint Frontend / Validate yarn install (push) Blocked by required conditions
golangci-lint / Detect whether code changed (push) Waiting to run
golangci-lint / go-fmt (push) Blocked by required conditions
golangci-lint / lint-go (push) Blocked by required conditions
govulncheck / govulncheck (push) Waiting to run
Verify i18n / verify-i18n (push) Waiting to run
Policybot / Check .policy.yml is valid (push) Waiting to run
End-to-end tests / Detect whether code changed (push) Waiting to run
End-to-end tests / Build backend (push) Blocked by required conditions
End-to-end tests / Build frontend (push) Blocked by required conditions
End-to-end tests / Verify Storybook (Playwright) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (1/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (2/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (3/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (4/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (5/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (6/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (7/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (8/8) (push) Blocked by required conditions
End-to-end tests / All Playwright tests complete (push) Blocked by required conditions
End-to-end tests / Report Playwright benchmarks (push) Blocked by required conditions
End-to-end tests / Publish metrics (push) Waiting to run
End-to-end tests / All E2E tests complete (push) Blocked by required conditions
Frontend tests / Detect whether code changed (push) Waiting to run
Frontend tests / Generate golden files (push) Blocked by required conditions
Frontend tests / Unit tests (1 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (10 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (11 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (12 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (13 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (14 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (15 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (16 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (2 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (3 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (4 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (5 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (6 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (7 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (8 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (9 / 16) (push) Blocked by required conditions
Frontend tests / Decoupled plugin tests (push) Blocked by required conditions
Frontend tests / Packages unit tests (push) Blocked by required conditions
Frontend tests / All frontend unit tests complete (push) Blocked by required conditions
Frontend tests / Devenv frontend-service build (push) Blocked by required conditions
Integration Tests (pgvector) / pgvector (push) Waiting to run
Integration Tests / Detect whether code changed (push) Waiting to run
Integration Tests / Sqlite (1/4) (push) Waiting to run
Integration Tests / Sqlite (2/4) (push) Waiting to run
Integration Tests / Sqlite (3/4) (push) Waiting to run
Integration Tests / Sqlite (4/4) (push) Waiting to run
Integration Tests / MySQL (1/16) (push) Waiting to run
Integration Tests / MySQL (10/16) (push) Waiting to run
Integration Tests / MySQL (11/16) (push) Waiting to run
Integration Tests / MySQL (12/16) (push) Waiting to run
Integration Tests / MySQL (13/16) (push) Waiting to run
Integration Tests / MySQL (14/16) (push) Waiting to run
Integration Tests / MySQL (15/16) (push) Waiting to run
Integration Tests / MySQL (16/16) (push) Waiting to run
Integration Tests / MySQL (2/16) (push) Waiting to run
Integration Tests / MySQL (3/16) (push) Waiting to run
Integration Tests / MySQL (4/16) (push) Waiting to run
Integration Tests / MySQL (5/16) (push) Waiting to run
Integration Tests / MySQL (6/16) (push) Waiting to run
Integration Tests / MySQL (7/16) (push) Waiting to run
Integration Tests / MySQL (8/16) (push) Waiting to run
Integration Tests / MySQL (9/16) (push) Waiting to run
Integration Tests / Postgres (1/16) (push) Waiting to run
Integration Tests / Postgres (10/16) (push) Waiting to run
Integration Tests / Postgres (11/16) (push) Waiting to run
Integration Tests / Postgres (12/16) (push) Waiting to run
Integration Tests / Postgres (13/16) (push) Waiting to run
Integration Tests / Postgres (14/16) (push) Waiting to run
Integration Tests / Postgres (15/16) (push) Waiting to run
Integration Tests / Postgres (16/16) (push) Waiting to run
Integration Tests / Postgres (2/16) (push) Waiting to run
Integration Tests / Postgres (3/16) (push) Waiting to run
Integration Tests / Postgres (4/16) (push) Waiting to run
Integration Tests / Postgres (5/16) (push) Waiting to run
Integration Tests / Postgres (6/16) (push) Waiting to run
Integration Tests / Postgres (7/16) (push) Waiting to run
Integration Tests / Postgres (8/16) (push) Waiting to run
Integration Tests / Postgres (9/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (1/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (10/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (11/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (12/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (13/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (14/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (15/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (16/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (2/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (3/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (4/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (5/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (6/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (7/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (8/16) (push) Waiting to run
Integration Tests / Sqlite Enterprise (9/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (1/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (10/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (11/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (12/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (13/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (14/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (15/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (16/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (2/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (3/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (4/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (5/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (6/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (7/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (8/16) (push) Waiting to run
Integration Tests / MySQL Enterprise (9/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (1/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (10/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (11/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (12/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (13/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (14/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (15/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (16/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (2/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (3/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (4/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (5/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (6/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (7/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (8/16) (push) Waiting to run
Integration Tests / Postgres Enterprise (9/16) (push) Waiting to run
Reject GitHub secrets / reject-gh-secrets (push) Waiting to run
Build Release Packages / setup (push) Waiting to run
Build Release Packages / Dispatch grafana-enterprise build (push) Blocked by required conditions
Build Release Packages / build frontend (push) Blocked by required conditions
Build Release Packages / build backend / darwin-amd64 (push) Blocked by required conditions
Build Release Packages / build backend / linux-amd64 (push) Blocked by required conditions
Build Release Packages / build backend / windows-amd64 (push) Blocked by required conditions
Build Release Packages / build backend / linux-armv6 (push) Blocked by required conditions
Build Release Packages / build backend / linux-armv7 (push) Blocked by required conditions
Build Release Packages / build backend / darwin-arm64 (push) Blocked by required conditions
Build Release Packages / build backend / linux-arm64 (push) Blocked by required conditions
Build Release Packages / build backend / windows-arm64 (push) Blocked by required conditions
Build Release Packages / build backend / linux-s390x (push) Blocked by required conditions
Build Release Packages / build backend / linux-riscv64 (push) Blocked by required conditions
Build Release Packages / targz / darwin-amd64 (push) Blocked by required conditions
Build Release Packages / targz / linux-amd64 (push) Blocked by required conditions
Build Release Packages / targz / windows-amd64 (push) Blocked by required conditions
Build Release Packages / targz / linux-armv6 (push) Blocked by required conditions
Build Release Packages / targz / linux-armv7 (push) Blocked by required conditions
Build Release Packages / targz / darwin-arm64 (push) Blocked by required conditions
Build Release Packages / targz / linux-arm64 (push) Blocked by required conditions
Build Release Packages / targz / windows-arm64 (push) Blocked by required conditions
Build Release Packages / targz / linux-s390x (push) Blocked by required conditions
Build Release Packages / targz / linux-riscv64 (push) Blocked by required conditions
Build Release Packages / deb / rpm / linux-amd64 (push) Blocked by required conditions
Build Release Packages / deb / rpm / linux-armv6 (push) Blocked by required conditions
Build Release Packages / deb / rpm / linux-armv7 (push) Blocked by required conditions
Build Release Packages / deb / rpm / linux-arm64 (push) Blocked by required conditions
Build Release Packages / deb / rpm / linux-s390x (push) Blocked by required conditions
Build Release Packages / deb / rpm / linux-riscv64 (push) Blocked by required conditions
Build Release Packages / verify rpm stig (linux-amd64) (push) Blocked by required conditions
Build Release Packages / docker / linux-amd64 (push) Blocked by required conditions
Build Release Packages / docker / linux-arm64 (push) Blocked by required conditions
Build Release Packages / docker / linux-s390x (push) Blocked by required conditions
Build Release Packages / docker / linux-armv7 (push) Blocked by required conditions
Build Release Packages / verify targz (linux-amd64) (push) Blocked by required conditions
Build Release Packages / verify packages (linux-amd64) (push) Blocked by required conditions
Build Release Packages / / windows / windows-amd64 (push) Blocked by required conditions
Build Release Packages / / windows / windows-arm64 (push) Blocked by required conditions
Build Release Packages / Upload targz / darwin-amd64 (push) Blocked by required conditions
Build Release Packages / Upload targz / darwin-arm64 (push) Blocked by required conditions
Build Release Packages / Upload targz / linux-amd64 (push) Blocked by required conditions
Build Release Packages / Upload targz / linux-arm64 (push) Blocked by required conditions
Build Release Packages / Upload targz / linux-armv6 (push) Blocked by required conditions
Build Release Packages / Upload targz / linux-armv7 (push) Blocked by required conditions
Build Release Packages / Upload targz / linux-s390x (push) Blocked by required conditions
Build Release Packages / Upload targz / linux-riscv64 (push) Blocked by required conditions
Build Release Packages / Upload targz / windows-amd64 (push) Blocked by required conditions
Build Release Packages / Upload targz / windows-arm64 (push) Blocked by required conditions
Build Release Packages / Upload deb/rpm / linux-amd64 (push) Blocked by required conditions
Build Release Packages / Upload deb/rpm / linux-arm64 (push) Blocked by required conditions
Build Release Packages / Upload deb/rpm / linux-armv6 (push) Blocked by required conditions
Build Release Packages / Upload deb/rpm / linux-armv7 (push) Blocked by required conditions
Build Release Packages / Upload deb/rpm / linux-s390x (push) Blocked by required conditions
Build Release Packages / Upload deb/rpm / linux-riscv64 (push) Blocked by required conditions
Build Release Packages / Upload docker (alpine) / linux-amd64 (push) Blocked by required conditions
Build Release Packages / Upload docker (alpine) / linux-arm64 (push) Blocked by required conditions
Build Release Packages / Upload docker (alpine) / linux-armv7 (push) Blocked by required conditions
Build Release Packages / Upload docker (alpine) / linux-s390x (push) Blocked by required conditions
Build Release Packages / Upload docker (alpine-slim) / linux-amd64 (push) Blocked by required conditions
Build Release Packages / Upload docker (alpine-slim) / linux-arm64 (push) Blocked by required conditions
Build Release Packages / Upload docker (alpine-slim) / linux-armv7 (push) Blocked by required conditions
Build Release Packages / Upload docker (alpine-slim) / linux-s390x (push) Blocked by required conditions
Build Release Packages / Upload docker (ubuntu) / linux-amd64 (push) Blocked by required conditions
Build Release Packages / Upload docker (ubuntu) / linux-arm64 (push) Blocked by required conditions
Build Release Packages / Upload docker (ubuntu) / linux-armv7 (push) Blocked by required conditions
Build Release Packages / Upload docker (ubuntu) / linux-s390x (push) Blocked by required conditions
Build Release Packages / Upload docker (ubuntu-slim) / linux-amd64 (push) Blocked by required conditions
Build Release Packages / Upload docker (ubuntu-slim) / linux-arm64 (push) Blocked by required conditions
Build Release Packages / Upload docker (ubuntu-slim) / linux-armv7 (push) Blocked by required conditions
Build Release Packages / Upload docker (ubuntu-slim) / linux-s390x (push) Blocked by required conditions
Build Release Packages / Upload docker (distroless) / linux-amd64 (push) Blocked by required conditions
Build Release Packages / Upload docker (distroless) / linux-arm64 (push) Blocked by required conditions
Build Release Packages / Upload docker (distroless) / linux-armv7 (push) Blocked by required conditions
Build Release Packages / Upload docker (distroless) / linux-s390x (push) Blocked by required conditions
Build Release Packages / Upload docker (distroless-slim) / linux-amd64 (push) Blocked by required conditions
Build Release Packages / Upload docker (distroless-slim) / linux-arm64 (push) Blocked by required conditions
Build Release Packages / Upload docker (distroless-slim) / linux-armv7 (push) Blocked by required conditions
Build Release Packages / Upload docker (distroless-slim) / linux-s390x (push) Blocked by required conditions
Build Release Packages / Upload windows / windows-amd64 (push) Blocked by required conditions
Build Release Packages / Upload windows / windows-arm64 (push) Blocked by required conditions
Build Release Packages / publish-dockerhub (artifacts-docker, , artifacts-docker-alpine-slim, -slim, alpine) (push) Blocked by required conditions
Build Release Packages / publish-dockerhub (artifacts-docker-distroless, -distroless, artifacts-docker-distroless-slim, -distroless-slim, distroless) (push) Blocked by required conditions
Build Release Packages / publish-dockerhub (artifacts-docker-ubuntu, -ubuntu, artifacts-docker-ubuntu-slim, -ubuntu-slim, ubuntu) (push) Blocked by required conditions
Build Release Packages / Run Meticulous tests (push) Blocked by required conditions
Build Release Packages / Dispatch publish NPM canaries (push) Blocked by required conditions
Build Release Packages / notify-pr (push) Blocked by required conditions
Run dashboard schema v2 e2e / dashboard-schema-v2-e2e (push) Waiting to run
Shellcheck / Shellcheck scripts (push) Waiting to run
Run Storybook a11y tests / Detect whether code changed (push) Waiting to run
Run Storybook a11y tests / Run Storybook a11y tests (dark theme) (push) Blocked by required conditions
Run Storybook a11y tests / Run Storybook a11y tests (deut_prot_dark theme) (push) Blocked by required conditions
Run Storybook a11y tests / Run Storybook a11y tests (deut_prot_light theme) (push) Blocked by required conditions
Run Storybook a11y tests / Run Storybook a11y tests (light theme) (push) Blocked by required conditions
Run Storybook a11y tests / Run Storybook a11y tests (tritanopia_dark theme) (push) Blocked by required conditions
Run Storybook a11y tests / Run Storybook a11y tests (tritanopia_light theme) (push) Blocked by required conditions
Run Storybook a11y tests / Storybook a11y tests (push) Blocked by required conditions
Swagger generated code / Detect whether code changed (push) Waiting to run
Swagger generated code / Verify committed API specs match (push) Blocked by required conditions
Dispatch sync to mirror / dispatch-job (push) Waiting to run
Alerting: remove MergeMatchers from ExtraConfiguration (#124856)
* alerting: remove MergeMatchers from ExtraConfiguration struct

Remove the MergeMatchers field and its equality-type validation from
ExtraConfiguration. Remove the corresponding parameter from the Prometheus
import API params struct and fix the orphaned comment that was attached to
the Replace field after the removal. Drop the field from the stored JSON
test fixture.

* alerting: remove merge matchers routing logic

Remove ValidateSubtreeMatchers, MergeRoutes, MergeInhibitRules, and
checkIfMatchersUsed from the merge package along with the associated error
variables (ErrInvalidMatchers, ErrDuplicateMatchers, ErrSubtreeMatchersConflict).
Remove ErrRouteConflictingMatchers and MakeErrRouteConflictingMatchers from
models/errors.go. Drop the conflict-check branches in UpdatePolicyTree and
UpdateManagedRoute that returned those errors.

* alerting: remove X-Grafana-Alerting-Merge-Matchers HTTP header

Remove the mergeMatchersHeader constant, parseMergeMatchersHeader, and
formatMergeMatchers from the Prometheus import API handler. Stop reading
the header on POST and stop echoing it back on GET.

* alerting: update tests after MergeMatchers removal

Remove MergeMatchers from all test fixtures and helper functions. Drop
tests that existed solely to cover merge-matchers validation
(TestValidateSubtreeMatchers, TestCheckIfMatchersUsed,
TestParseMergeMatchersHeader, TestFormatMergeMatchers,
ErrRouteConflictingMatchers scenario). Remove the now-obsolete
"cannot be fully merged" test case in TestConfigRevisionImported.
Collapse the duplicate TestApplyConfigWithExtraConfigsConvertsMimirReceivers
into TestApplyConfigWithExtraConfigs and update its assertions to reflect
that Mimir receivers are always converted regardless of any flag.
Add TestApplyConfigWithExtraConfigs and
TestCompareAndSendConfigurationConvertsMimirReceivers to cover the
receiver-conversion path.

Update TestIntegrationExtraConfigsConflicts to test the conflict that
still exists: creating a managed route whose name matches an imported
route's identifier returns a Conflict error.

* alerting: remove dead MergeExtraConfig calls from UpdateManagedRoute and DeleteManagedRoute

The calls were either no-ops (Update: error silently logged and ignored)
or guarding against scenarios that no longer exist (Delete: merge
matchers conflict was the only way MergeExtraConfig could fail on a
valid config). Neither call has tests covering them.
2026-05-20 09:09:46 -04:00

259 lines
8.4 KiB
Go

package alerting
import (
"context"
"fmt"
"net/http"
"net/url"
"testing"
"time"
"github.com/stretchr/testify/require"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/tests/alertmanager"
"github.com/grafana/grafana/pkg/tests/testinfra"
"github.com/grafana/grafana/pkg/util/testutil"
)
// TestIntegrationRemoteAlertmanagerConfigUpload tests that when we post an alertmanager
// configuration to Grafana with remote alertmanager enabled, it gets uploaded to the remote Mimir.
func TestIntegrationRemoteAlertmanagerConfigUpload(t *testing.T) {
testutil.SkipIntegrationTestInShortMode(t)
testinfra.SQLiteIntegrationTest(t)
s, err := alertmanager.NewAlertmanagerScenario()
require.NoError(t, err)
defer s.Close()
s.Mimir = alertmanager.NewMimirService("mimir")
require.NoError(t, s.StartAndWaitReady(s.Mimir))
mimirEndpoint := "http://" + s.Mimir.HTTPEndpoint()
dir, gpath := testinfra.CreateGrafDir(t, testinfra.GrafanaOpts{
DisableLegacyAlerting: true,
EnableUnifiedAlerting: true,
DisableAnonymous: true,
AppModeProduction: true,
EnableFeatureToggles: []string{
"alertmanagerRemotePrimary",
"alertingMultiplePolicies",
"alertingImportAlertmanagerAPI",
},
RemoteAlertmanagerURL: mimirEndpoint,
})
grafanaListedAddr, _ := testinfra.StartGrafanaEnv(t, dir, gpath)
apiClient := newAlertingApiClient(grafanaListedAddr, "admin", "admin")
mimirClient, err := alertmanager.NewMimirClient(mimirEndpoint, "1")
require.NoError(t, err)
// Wait for Grafana to be ready
require.Eventually(t, func() bool {
_, status, _ := apiClient.GetAlertmanagerConfigWithStatus(t)
return status == http.StatusOK
}, 30*time.Second, time.Second, "Grafana failed to start")
// Check that the initial Mimir config contains the default Grafana configuration
initialMimirConfig, err := mimirClient.GetGrafanaAlertmanagerConfig(context.Background())
require.NoError(t, err)
require.NotNil(t, initialMimirConfig) // Grafana automatically syncs default config to remote alertmanager
require.NotNil(t, initialMimirConfig.GrafanaAlertmanagerConfig)
// Initially there is just the default empty receiver
receivers := initialMimirConfig.GrafanaAlertmanagerConfig.AlertmanagerConfig.Receivers
require.Len(t, receivers, 1)
require.Equal(t, "empty", receivers[0].Name)
// Now upload a new extra config and check that it gets uploaded to Mimir
testAlertmanagerConfigYAML := `
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 1h
receiver: extra-webhook
receivers:
- name: extra-webhook
webhook_configs:
- url: 'http://localhost'
`
headers := map[string]string{
"Content-Type": "application/yaml",
"X-Grafana-Alerting-Config-Identifier": "external-system",
}
amConfig := apimodels.AlertmanagerUserConfig{
AlertmanagerConfig: testAlertmanagerConfigYAML,
TemplateFiles: map[string]string{
"test.tmpl": `{{ define "test.template" }}Test template for remote sync{{ end }}`,
},
}
// Post the configuration to Grafana
response := apiClient.ConvertPrometheusPostAlertmanagerConfig(t, amConfig, headers)
require.Equal(t, "success", response.Status)
_, status, _ := apiClient.GetAlertmanagerConfigWithStatus(t)
require.Equal(t, http.StatusOK, status)
// Check that the configuration was successfully sent to Mimir and contains the new receiver
finalMimirConfig, err := mimirClient.GetGrafanaAlertmanagerConfig(context.Background())
require.NoError(t, err)
require.NotNil(t, finalMimirConfig)
require.NotNil(t, finalMimirConfig.GrafanaAlertmanagerConfig)
receivers = finalMimirConfig.GrafanaAlertmanagerConfig.AlertmanagerConfig.Receivers
require.Len(t, receivers, 2)
var foundDefault, foundExtraSlack bool
for _, receiver := range receivers {
switch receiver.Name {
case "empty":
foundDefault = true
require.Len(t, receiver.GrafanaManagedReceivers, 0)
case "extra-webhook":
foundExtraSlack = true
require.Len(t, receiver.GrafanaManagedReceivers, 1)
}
}
require.True(t, foundDefault, "Default receiver not found")
require.True(t, foundExtraSlack, "Extra slack receiver not found")
}
// TestIntegrationRemoteAlertmanagerHistoricalConfigActivation tests that when we activate
// a historical alertmanager configuration with extra configs, it gets properly decrypted
// and uploaded to the remote Mimir.
func TestIntegrationRemoteAlertmanagerHistoricalConfigActivation(t *testing.T) {
testutil.SkipIntegrationTestInShortMode(t)
testinfra.SQLiteIntegrationTest(t)
s, err := alertmanager.NewAlertmanagerScenario()
require.NoError(t, err)
defer s.Close()
s.Mimir = alertmanager.NewMimirService("mimir")
require.NoError(t, s.StartAndWaitReady(s.Mimir))
mimirEndpoint := "http://" + s.Mimir.HTTPEndpoint()
dir, gpath := testinfra.CreateGrafDir(t, testinfra.GrafanaOpts{
DisableLegacyAlerting: true,
EnableUnifiedAlerting: true,
DisableAnonymous: true,
AppModeProduction: true,
EnableFeatureToggles: []string{
"alertmanagerRemotePrimary",
"alertingMultiplePolicies",
"alertingImportAlertmanagerAPI",
},
RemoteAlertmanagerURL: mimirEndpoint,
})
grafanaListedAddr, _ := testinfra.StartGrafanaEnv(t, dir, gpath)
apiClient := newAlertingApiClient(grafanaListedAddr, "admin", "admin")
mimirClient, err := alertmanager.NewMimirClient(mimirEndpoint, "1")
require.NoError(t, err)
require.Eventually(t, func() bool {
_, status, _ := apiClient.GetAlertmanagerConfigWithStatus(t)
return status == http.StatusOK
}, 30*time.Second, time.Second, "Grafana failed to start")
// Upload configuration with extra configs
testAlertmanagerConfigYAML := `
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 1h
receiver: old-webhook
receivers:
- name: old-webhook
webhook_configs:
- url: 'http://localhost'
`
headers := map[string]string{
"Content-Type": "application/yaml",
"X-Grafana-Alerting-Config-Identifier": "historical-system",
}
amConfig := apimodels.AlertmanagerUserConfig{
AlertmanagerConfig: testAlertmanagerConfigYAML,
TemplateFiles: map[string]string{
"historical.tmpl": `{{ define "historical.template" }}Historical template{{ end }}`,
},
}
response := apiClient.ConvertPrometheusPostAlertmanagerConfig(t, amConfig, headers)
require.Equal(t, "success", response.Status)
// Get the configuration history to find the most recent config
historyResponse := getAlertmanagerConfigHistory(t, apiClient)
require.NotEmpty(t, historyResponse)
var mostRecentID int64
for _, entry := range historyResponse {
if entry.ID > mostRecentID {
mostRecentID = entry.ID
}
}
require.Greater(t, mostRecentID, int64(0), "Should have found a historical configuration")
// Activate the historical configuration
activateHistoricalConfiguration(t, apiClient, mostRecentID)
// Verify the configuration
finalMimirConfig, err := mimirClient.GetGrafanaAlertmanagerConfig(context.Background())
require.NoError(t, err)
require.NotNil(t, finalMimirConfig)
require.NotNil(t, finalMimirConfig.GrafanaAlertmanagerConfig)
receivers := finalMimirConfig.GrafanaAlertmanagerConfig.AlertmanagerConfig.Receivers
require.Len(t, receivers, 2)
found := false
for _, receiver := range receivers {
if receiver.Name == "old-webhook" {
found = true
require.Len(t, receiver.GrafanaManagedReceivers, 1)
break
}
}
require.True(t, found)
}
func getAlertmanagerConfigHistory(t *testing.T, client apiClient) []apimodels.GettableHistoricUserConfig {
t.Helper()
u, err := url.Parse(fmt.Sprintf("%s/api/alertmanager/grafana/config/history", client.url))
require.NoError(t, err)
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
require.NoError(t, err)
history, _, _ := sendRequestJSON[[]apimodels.GettableHistoricUserConfig](t, req, http.StatusOK)
return history
}
func activateHistoricalConfiguration(t *testing.T, client apiClient, configID int64) {
t.Helper()
u, err := url.Parse(fmt.Sprintf("%s/api/alertmanager/grafana/config/history/%d/_activate", client.url, configID))
require.NoError(t, err)
req, err := http.NewRequest(http.MethodPost, u.String(), nil)
require.NoError(t, err)
response, statusCode, body := sendRequestJSON[map[string]string](t, req, http.StatusAccepted)
if statusCode != http.StatusAccepted {
t.Fatalf("Expected status code %d but got %d. Response body: %s", http.StatusAccepted, statusCode, body)
}
require.Equal(t, "configuration activated", response["message"])
}