mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Add notification policy provisioning file export (#70009)
* Alerting: Add notification policy provisioning file export - Add provisioning API endpoint for exporting notification policies. - Add option in notification policy view ellipsis dropdown for exporting. - Update various provisioning documentation.
This commit is contained in:
@@ -13,11 +13,14 @@ import ConditionalWrap from 'app/features/alerting/components/ConditionalWrap';
|
||||
import { RouteWithID, Receiver, ObjectMatcher, AlertmanagerGroup } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { ReceiversState } from 'app/types';
|
||||
|
||||
import { isOrgAdmin } from '../../../../plugins/admin/permissions';
|
||||
import { INTEGRATION_ICONS } from '../../types/contact-points';
|
||||
import { getNotificationsPermissions } from '../../utils/access-control';
|
||||
import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';
|
||||
import { normalizeMatchers } from '../../utils/matchers';
|
||||
import { createContactPointLink, createMuteTimingLink } from '../../utils/misc';
|
||||
import { getInheritedProperties, InhertitableProperties } from '../../utils/notification-policies';
|
||||
import { createUrl } from '../../utils/url';
|
||||
import { HoverCard } from '../HoverCard';
|
||||
import { Label } from '../Label';
|
||||
import { MetaText } from '../MetaText';
|
||||
@@ -72,6 +75,7 @@ const Policy: FC<PolicyComponentProps> = ({
|
||||
const permissions = getNotificationsPermissions(alertManagerSourceName);
|
||||
const canEditRoutes = contextSrv.hasPermission(permissions.update);
|
||||
const canDeleteRoutes = contextSrv.hasPermission(permissions.delete);
|
||||
const canReadProvisioning = contextSrv.hasAccess(permissions.provisioning.read, isOrgAdmin());
|
||||
|
||||
const contactPoint = currentRoute.receiver;
|
||||
const continueMatching = currentRoute.continue ?? false;
|
||||
@@ -122,6 +126,9 @@ const Policy: FC<PolicyComponentProps> = ({
|
||||
? sumBy(matchingAlertGroups, (group) => group.alerts.length)
|
||||
: undefined;
|
||||
|
||||
const isGrafanaAM = alertManagerSourceName === GRAFANA_RULES_SOURCE_NAME;
|
||||
const showExport = isGrafanaAM && isDefaultPolicy && canReadProvisioning;
|
||||
|
||||
// TODO dead branch detection, warnings for all sort of configs that won't work or will never be activated
|
||||
return (
|
||||
<Stack direction="column" gap={1.5}>
|
||||
@@ -148,56 +155,73 @@ const Policy: FC<PolicyComponentProps> = ({
|
||||
{/* TODO maybe we should move errors to the gutter instead? */}
|
||||
{errors.length > 0 && <Errors errors={errors} />}
|
||||
{provisioned && <ProvisioningBadge />}
|
||||
{readOnly ? null : (
|
||||
{readOnly && !showExport ? null : (
|
||||
<Stack direction="row" gap={0.5}>
|
||||
<ConditionalWrap shouldWrap={provisioned} wrap={ProvisionedTooltip}>
|
||||
<Button
|
||||
variant="secondary"
|
||||
icon="plus"
|
||||
size="sm"
|
||||
onClick={() => onAddPolicy(currentRoute)}
|
||||
disabled={provisioned}
|
||||
type="button"
|
||||
>
|
||||
New nested policy
|
||||
</Button>
|
||||
</ConditionalWrap>
|
||||
{!readOnly && (
|
||||
<ConditionalWrap shouldWrap={provisioned} wrap={ProvisionedTooltip}>
|
||||
<Button
|
||||
variant="secondary"
|
||||
icon="plus"
|
||||
size="sm"
|
||||
onClick={() => onAddPolicy(currentRoute)}
|
||||
disabled={provisioned}
|
||||
type="button"
|
||||
>
|
||||
New nested policy
|
||||
</Button>
|
||||
</ConditionalWrap>
|
||||
)}
|
||||
|
||||
<ConditionalWrap shouldWrap={provisioned} wrap={ProvisionedTooltip}>
|
||||
<Dropdown
|
||||
overlay={
|
||||
<Menu>
|
||||
<Dropdown
|
||||
overlay={
|
||||
<Menu>
|
||||
{!readOnly && (
|
||||
<ConditionalWrap shouldWrap={provisioned} wrap={ProvisionedTooltip}>
|
||||
<Menu.Item
|
||||
icon="edit"
|
||||
disabled={!isEditable || provisioned}
|
||||
label="Edit"
|
||||
onClick={() => onEditPolicy(currentRoute, isDefaultPolicy)}
|
||||
/>
|
||||
</ConditionalWrap>
|
||||
)}
|
||||
{showExport && (
|
||||
<Menu.Item
|
||||
icon="edit"
|
||||
disabled={!isEditable}
|
||||
label="Edit"
|
||||
onClick={() => onEditPolicy(currentRoute, isDefaultPolicy)}
|
||||
icon="download-alt"
|
||||
label="Export"
|
||||
url={createUrl('/api/v1/provisioning/policies/export', {
|
||||
download: 'true',
|
||||
format: 'yaml',
|
||||
})}
|
||||
target="_blank"
|
||||
/>
|
||||
{isDeletable && (
|
||||
<>
|
||||
<Menu.Divider />
|
||||
)}
|
||||
{!readOnly && isDeletable && (
|
||||
<>
|
||||
<Menu.Divider />
|
||||
<ConditionalWrap shouldWrap={provisioned} wrap={ProvisionedTooltip}>
|
||||
<Menu.Item
|
||||
destructive
|
||||
icon="trash-alt"
|
||||
disabled={!isDeletable || provisioned}
|
||||
label="Delete"
|
||||
onClick={() => onDeletePolicy(currentRoute)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<Button
|
||||
icon="ellipsis-h"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
type="button"
|
||||
aria-label="more-actions"
|
||||
data-testid="more-actions"
|
||||
disabled={provisioned}
|
||||
/>
|
||||
</Dropdown>
|
||||
</ConditionalWrap>
|
||||
</ConditionalWrap>
|
||||
</>
|
||||
)}
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<Button
|
||||
icon="ellipsis-h"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
type="button"
|
||||
aria-label="more-actions"
|
||||
data-testid="more-actions"
|
||||
/>
|
||||
</Dropdown>
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
|
||||
Reference in New Issue
Block a user