mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Use new readonly permission endpoints for getting contact points and mute timings (#82132)
* use new read only contact points list endpoint in simplified routing section * Dont use alertmanager endpoint to get groupby defaults * Use the new read only endpoint for mute timings in route settings * review suggestions * Rename hook * Use options in params for useContactPointsWithStatus hook * Refactor useContactPointsWithStatus * second part of the enhanceContactPointsWithMetadata refactor
This commit is contained in:
@@ -27,7 +27,13 @@ const RECEIVER_STATUS_POLLING_INTERVAL = 10 * 1000; // 10 seconds
|
||||
* 3. (if available) additional metadata about Grafana Managed contact points
|
||||
* 4. (if available) the OnCall plugin metadata
|
||||
*/
|
||||
export function useContactPointsWithStatus() {
|
||||
interface UseContactPointsWithStatusOptions {
|
||||
includePoliciesCount: boolean;
|
||||
}
|
||||
|
||||
export function useContactPointsWithStatus(
|
||||
{ includePoliciesCount }: UseContactPointsWithStatusOptions = { includePoliciesCount: true }
|
||||
) {
|
||||
const { selectedAlertmanager, isGrafanaAlertmanager } = useAlertmanager();
|
||||
const { installed: onCallPluginInstalled, loading: onCallPluginStatusLoading } = usePluginBridge(
|
||||
SupportedPlugin.OnCall
|
||||
@@ -64,6 +70,7 @@ export function useContactPointsWithStatus() {
|
||||
}
|
||||
|
||||
// fetch the latest config from the Alertmanager
|
||||
// we use this endpoint only when we need to get the number of policies
|
||||
const fetchAlertmanagerConfiguration = alertmanagerApi.endpoints.getAlertmanagerConfiguration.useQuery(
|
||||
selectedAlertmanager!,
|
||||
{
|
||||
@@ -73,31 +80,56 @@ export function useContactPointsWithStatus() {
|
||||
...result,
|
||||
contactPoints: result.data
|
||||
? enhanceContactPointsWithMetadata(
|
||||
result.data,
|
||||
fetchContactPointsStatus.data,
|
||||
fetchReceiverMetadata.data,
|
||||
onCallMetadata
|
||||
onCallMetadata,
|
||||
result.data.alertmanager_config.receivers ?? [],
|
||||
result.data
|
||||
)
|
||||
: [],
|
||||
}),
|
||||
skip: !includePoliciesCount,
|
||||
}
|
||||
);
|
||||
|
||||
// for Grafana Managed Alertmanager, we use the new read-only endpoint for getting the list of contact points
|
||||
const fetchGrafanaContactPoints = alertmanagerApi.endpoints.getContactPointsList.useQuery(undefined, {
|
||||
refetchOnFocus: true,
|
||||
refetchOnReconnect: true,
|
||||
selectFromResult: (result) => ({
|
||||
...result,
|
||||
contactPoints: result.data
|
||||
? enhanceContactPointsWithMetadata(
|
||||
fetchContactPointsStatus.data,
|
||||
fetchReceiverMetadata.data,
|
||||
onCallMetadata,
|
||||
result.data, // contact points from the new readonly endpoint
|
||||
undefined //no config data
|
||||
)
|
||||
: [],
|
||||
}),
|
||||
skip: includePoliciesCount || !isGrafanaAlertmanager,
|
||||
});
|
||||
|
||||
// we will fail silently for fetching OnCall plugin status and integrations
|
||||
const error = fetchAlertmanagerConfiguration.error ?? fetchContactPointsStatus.error;
|
||||
const error =
|
||||
fetchAlertmanagerConfiguration.error || fetchGrafanaContactPoints.error || fetchContactPointsStatus.error;
|
||||
const isLoading =
|
||||
fetchAlertmanagerConfiguration.isLoading ||
|
||||
fetchGrafanaContactPoints.isLoading ||
|
||||
fetchContactPointsStatus.isLoading ||
|
||||
onCallPluginStatusLoading ||
|
||||
onCallPluginIntegrationsLoading;
|
||||
|
||||
const contactPoints = fetchAlertmanagerConfiguration.contactPoints.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
const unsortedContactPoints = includePoliciesCount
|
||||
? fetchAlertmanagerConfiguration.contactPoints
|
||||
: fetchGrafanaContactPoints.contactPoints;
|
||||
const contactPoints = unsortedContactPoints.sort((a, b) => a.name.localeCompare(b.name));
|
||||
return {
|
||||
error,
|
||||
isLoading,
|
||||
contactPoints,
|
||||
refetchReceivers: fetchAlertmanagerConfiguration.refetch,
|
||||
refetchReceivers: fetchGrafanaContactPoints.refetch,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
GrafanaManagedContactPoint,
|
||||
GrafanaManagedReceiverConfig,
|
||||
MatcherOperator,
|
||||
Receiver,
|
||||
Route,
|
||||
} from 'app/plugins/datasource/alertmanager/types';
|
||||
import { NotifierDTO, NotifierStatus, ReceiversStateDTO } from 'app/types';
|
||||
@@ -30,6 +31,9 @@ export function isProvisioned(contactPoint: GrafanaManagedContactPoint) {
|
||||
|
||||
// TODO we should really add some type information to these receiver settings...
|
||||
export function getReceiverDescription(receiver: ReceiverConfigWithMetadata): ReactNode | undefined {
|
||||
if (!receiver.settings) {
|
||||
return undefined;
|
||||
}
|
||||
switch (receiver.type) {
|
||||
case 'email': {
|
||||
const hasEmailAddresses = 'addresses' in receiver.settings; // when dealing with alertmanager email_configs we don't normalize the settings
|
||||
@@ -87,7 +91,7 @@ export interface ReceiverConfigWithMetadata extends GrafanaManagedReceiverConfig
|
||||
}
|
||||
|
||||
export interface ContactPointWithMetadata extends GrafanaManagedContactPoint {
|
||||
numberOfPolicies: number;
|
||||
numberOfPolicies?: number; // now is optional as we don't have the data from the read-only endpoint
|
||||
grafana_managed_receiver_configs: ReceiverConfigWithMetadata[];
|
||||
}
|
||||
|
||||
@@ -95,30 +99,36 @@ export interface ContactPointWithMetadata extends GrafanaManagedContactPoint {
|
||||
* This function adds the status information for each of the integrations (contact point types) in a contact point
|
||||
* 1. we iterate over all contact points
|
||||
* 2. for each contact point we "enhance" it with the status or "undefined" for vanilla Alertmanager
|
||||
* contactPoints: list of contact points
|
||||
* alertmanagerConfiguration: optional as is passed when we need to get number of policies for each contact point
|
||||
* and we prefer using the data from the read-only endpoint.
|
||||
*/
|
||||
export function enhanceContactPointsWithMetadata(
|
||||
result: AlertManagerCortexConfig,
|
||||
status: ReceiversStateDTO[] = [],
|
||||
notifiers: NotifierDTO[] = [],
|
||||
onCallIntegrations: OnCallIntegrationDTO[] | undefined | null
|
||||
onCallIntegrations: OnCallIntegrationDTO[] | undefined | null,
|
||||
contactPoints: Receiver[],
|
||||
alertmanagerConfiguration?: AlertManagerCortexConfig
|
||||
): ContactPointWithMetadata[] {
|
||||
const contactPoints = result.alertmanager_config.receivers ?? [];
|
||||
|
||||
// compute the entire inherited tree before finding what notification policies are using a particular contact point
|
||||
const fullyInheritedTree = computeInheritedTree(result?.alertmanager_config?.route ?? {});
|
||||
const fullyInheritedTree = computeInheritedTree(alertmanagerConfiguration?.alertmanager_config?.route ?? {});
|
||||
const usedContactPoints = getUsedContactPoints(fullyInheritedTree);
|
||||
const usedContactPointsByName = countBy(usedContactPoints);
|
||||
|
||||
return contactPoints.map((contactPoint) => {
|
||||
const contactPointsList = alertmanagerConfiguration
|
||||
? alertmanagerConfiguration?.alertmanager_config.receivers ?? []
|
||||
: contactPoints ?? [];
|
||||
|
||||
return contactPointsList.map((contactPoint) => {
|
||||
const receivers = extractReceivers(contactPoint);
|
||||
const statusForReceiver = status.find((status) => status.name === contactPoint.name);
|
||||
|
||||
return {
|
||||
...contactPoint,
|
||||
numberOfPolicies: usedContactPointsByName[contactPoint.name] ?? 0,
|
||||
numberOfPolicies:
|
||||
alertmanagerConfiguration && usedContactPointsByName && (usedContactPointsByName[contactPoint.name] ?? 0),
|
||||
grafana_managed_receiver_configs: receivers.map((receiver, index) => {
|
||||
const isOnCallReceiver = receiver.type === ReceiverTypes.OnCall;
|
||||
|
||||
return {
|
||||
...receiver,
|
||||
[RECEIVER_STATUS_KEY]: statusForReceiver?.integrations[index],
|
||||
@@ -130,6 +140,7 @@ export function enhanceContactPointsWithMetadata(
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function isAutoGeneratedPolicy(route: Route) {
|
||||
const simplifiedRoutingToggleEnabled = config.featureToggles.alertingSimplifiedRouting ?? false;
|
||||
if (!simplifiedRoutingToggleEnabled) {
|
||||
|
||||
Reference in New Issue
Block a user