Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[v10.0.x] Alerting: Display correct results when using different filt…
…ers on alerting panels (#70639) Alerting: Display correct results when using different filters on alerting panels (#70482) * Trigger separate rules request for each alerting panel in a dashboard * Add RTK method to fetch prom rules * Use RTKQuery to get prom rules in UnifiedAlertList * Fix lint * Mock promRules call * Address PR comments * Fix tests (cherry picked from commit f17c49e)
- Loading branch information
Showing
7 changed files
with
332 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { Matcher } from 'app/plugins/datasource/alertmanager/types'; | ||
import { RuleIdentifier, RuleNamespace } from 'app/types/unified-alerting'; | ||
import { PromRulesResponse } from 'app/types/unified-alerting-dto'; | ||
|
||
import { GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource'; | ||
import { isCloudRuleIdentifier, isPrometheusRuleIdentifier } from '../utils/rules'; | ||
|
||
import { alertingApi } from './alertingApi'; | ||
import { | ||
FetchPromRulesFilter, | ||
groupRulesByFileName, | ||
paramsWithMatcherAndState, | ||
prepareRulesFilterQueryParams, | ||
} from './prometheus'; | ||
export interface Datasource { | ||
type: string; | ||
uid: string; | ||
} | ||
|
||
export const PREVIEW_URL = '/api/v1/rule/test/grafana'; | ||
export const PROM_RULES_URL = 'api/prometheus/grafana/api/v1/rules'; | ||
|
||
export const alertRuleApi = alertingApi.injectEndpoints({ | ||
endpoints: (build) => ({ | ||
prometheusRulesByNamespace: build.query< | ||
RuleNamespace[], | ||
{ | ||
limitAlerts?: number; | ||
identifier?: RuleIdentifier; | ||
filter?: FetchPromRulesFilter; | ||
state?: string[]; | ||
matcher?: Matcher[]; | ||
} | ||
>({ | ||
query: ({ limitAlerts, identifier, filter, state, matcher }) => { | ||
const searchParams = new URLSearchParams(); | ||
|
||
// if we're fetching for Grafana managed rules, we should add a limit to the number of alert instances | ||
// we do this because the response is large otherwise and we don't show all of them in the UI anyway. | ||
if (limitAlerts) { | ||
searchParams.set('limit_alerts', String(limitAlerts)); | ||
} | ||
|
||
if (identifier && (isPrometheusRuleIdentifier(identifier) || isCloudRuleIdentifier(identifier))) { | ||
searchParams.set('file', identifier.namespace); | ||
searchParams.set('rule_group', identifier.groupName); | ||
} | ||
|
||
const params = prepareRulesFilterQueryParams(searchParams, filter); | ||
|
||
return { url: PROM_RULES_URL, params: paramsWithMatcherAndState(params, state, matcher) }; | ||
}, | ||
transformResponse: (response: PromRulesResponse): RuleNamespace[] => { | ||
return groupRulesByFileName(response.data.groups, GRAFANA_RULES_SOURCE_NAME); | ||
}, | ||
}), | ||
}), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
import { rest } from 'msw'; | ||
import { setupServer, SetupServer } from 'msw/node'; | ||
import 'whatwg-fetch'; | ||
|
||
import { setBackendSrv } from '@grafana/runtime'; | ||
|
||
import { backendSrv } from '../../../core/services/backend_srv'; | ||
import { | ||
AlertmanagerConfig, | ||
AlertManagerCortexConfig, | ||
EmailConfig, | ||
MatcherOperator, | ||
Receiver, | ||
Route, | ||
} from '../../../plugins/datasource/alertmanager/types'; | ||
|
||
class AlertmanagerConfigBuilder { | ||
private alertmanagerConfig: AlertmanagerConfig = { receivers: [] }; | ||
|
||
addReceivers(configure: (builder: AlertmanagerReceiverBuilder) => void): AlertmanagerConfigBuilder { | ||
const receiverBuilder = new AlertmanagerReceiverBuilder(); | ||
configure(receiverBuilder); | ||
this.alertmanagerConfig.receivers?.push(receiverBuilder.build()); | ||
return this; | ||
} | ||
|
||
withRoute(configure: (routeBuilder: AlertmanagerRouteBuilder) => void): AlertmanagerConfigBuilder { | ||
const routeBuilder = new AlertmanagerRouteBuilder(); | ||
configure(routeBuilder); | ||
|
||
this.alertmanagerConfig.route = routeBuilder.build(); | ||
|
||
return this; | ||
} | ||
|
||
build() { | ||
return this.alertmanagerConfig; | ||
} | ||
} | ||
|
||
class AlertmanagerRouteBuilder { | ||
private route: Route = { routes: [], object_matchers: [] }; | ||
|
||
withReceiver(receiver: string): AlertmanagerRouteBuilder { | ||
this.route.receiver = receiver; | ||
return this; | ||
} | ||
withoutReceiver(): AlertmanagerRouteBuilder { | ||
return this; | ||
} | ||
withEmptyReceiver(): AlertmanagerRouteBuilder { | ||
this.route.receiver = ''; | ||
return this; | ||
} | ||
|
||
addRoute(configure: (builder: AlertmanagerRouteBuilder) => void): AlertmanagerRouteBuilder { | ||
const routeBuilder = new AlertmanagerRouteBuilder(); | ||
configure(routeBuilder); | ||
this.route.routes?.push(routeBuilder.build()); | ||
return this; | ||
} | ||
|
||
addMatcher(key: string, operator: MatcherOperator, value: string): AlertmanagerRouteBuilder { | ||
this.route.object_matchers?.push([key, operator, value]); | ||
return this; | ||
} | ||
|
||
build() { | ||
return this.route; | ||
} | ||
} | ||
|
||
class EmailConfigBuilder { | ||
private emailConfig: EmailConfig = { to: '' }; | ||
|
||
withTo(to: string): EmailConfigBuilder { | ||
this.emailConfig.to = to; | ||
return this; | ||
} | ||
|
||
build() { | ||
return this.emailConfig; | ||
} | ||
} | ||
|
||
class AlertmanagerReceiverBuilder { | ||
private receiver: Receiver = { name: '', email_configs: [] }; | ||
|
||
withName(name: string): AlertmanagerReceiverBuilder { | ||
this.receiver.name = name; | ||
return this; | ||
} | ||
|
||
addEmailConfig(configure: (builder: EmailConfigBuilder) => void): AlertmanagerReceiverBuilder { | ||
const builder = new EmailConfigBuilder(); | ||
configure(builder); | ||
this.receiver.email_configs?.push(builder.build()); | ||
return this; | ||
} | ||
|
||
build() { | ||
return this.receiver; | ||
} | ||
} | ||
|
||
export function mockApi(server: SetupServer) { | ||
return { | ||
getAlertmanagerConfig: (amName: string, configure: (builder: AlertmanagerConfigBuilder) => void) => { | ||
const builder = new AlertmanagerConfigBuilder(); | ||
configure(builder); | ||
|
||
server.use( | ||
rest.get(`api/alertmanager/${amName}/config/api/v1/alerts`, (req, res, ctx) => | ||
res( | ||
ctx.status(200), | ||
ctx.json<AlertManagerCortexConfig>({ | ||
alertmanager_config: builder.build(), | ||
template_files: {}, | ||
}) | ||
) | ||
) | ||
); | ||
}, | ||
}; | ||
} | ||
|
||
// Creates a MSW server and sets up beforeAll and afterAll handlers for it | ||
export function setupMswServer() { | ||
const server = setupServer(); | ||
|
||
beforeAll(() => { | ||
setBackendSrv(backendSrv); | ||
server.listen({ onUnhandledRequest: 'error' }); | ||
}); | ||
|
||
afterAll(() => { | ||
server.close(); | ||
}); | ||
|
||
return server; | ||
} |
10 changes: 10 additions & 0 deletions
10
public/app/features/alerting/unified/mocks/alertRuleApi.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { rest } from 'msw'; | ||
import { SetupServer } from 'msw/node'; | ||
|
||
import { PromRulesResponse } from 'app/types/unified-alerting-dto'; | ||
|
||
import { PROM_RULES_URL } from '../api/alertRuleApi'; | ||
|
||
export function mockPromRulesApiResponse(server: SetupServer, result: PromRulesResponse) { | ||
server.use(rest.get(PROM_RULES_URL, (req, res, ctx) => res(ctx.json<PromRulesResponse>(result)))); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.