mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* add FGAC actions for silences table * redirect users without permissions * hide silence button in rules list * add permissions checks to routes * add read action for silences page * add permissions checks to navigation * add additional access checks for rule viewing * create authorize component * add tests for silences * hide alerting nav for users without access * nolint: gocyclo * add permission check to alert details * add check for external instances * remove unecessary new lines * use correct actions for alert details * fix failing tests Co-authored-by: Yuriy Tseretyan <yuriy.tseretyan@grafana.com>
94 lines
3.2 KiB
TypeScript
94 lines
3.2 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import { GrafanaTheme2 } from '@grafana/data';
|
|
import { LinkButton, useStyles2 } from '@grafana/ui';
|
|
import { contextSrv } from 'app/core/services/context_srv';
|
|
import { AlertmanagerAlert, AlertState } from 'app/plugins/datasource/alertmanager/types';
|
|
import { AccessControlAction } from 'app/types';
|
|
import React, { FC } from 'react';
|
|
import { isGrafanaRulesSource } from '../../utils/datasource';
|
|
import { makeAMLink, makeLabelBasedSilenceLink } from '../../utils/misc';
|
|
import { AnnotationDetailsField } from '../AnnotationDetailsField';
|
|
import { Authorize } from '../Authorize';
|
|
|
|
interface AmNotificationsAlertDetailsProps {
|
|
alertManagerSourceName: string;
|
|
alert: AlertmanagerAlert;
|
|
}
|
|
|
|
export const AlertDetails: FC<AmNotificationsAlertDetailsProps> = ({ alert, alertManagerSourceName }) => {
|
|
const styles = useStyles2(getStyles);
|
|
const isExternalAM = !isGrafanaRulesSource(alertManagerSourceName);
|
|
return (
|
|
<>
|
|
<div className={styles.actionsRow}>
|
|
<Authorize
|
|
actions={
|
|
isExternalAM
|
|
? [AccessControlAction.AlertingInstancesExternalWrite]
|
|
: [AccessControlAction.AlertingInstanceCreate, AccessControlAction.AlertingInstanceUpdate]
|
|
}
|
|
fallback={contextSrv.isEditor}
|
|
>
|
|
{alert.status.state === AlertState.Suppressed && (
|
|
<LinkButton
|
|
href={`${makeAMLink(
|
|
'/alerting/silences',
|
|
alertManagerSourceName
|
|
)}&silenceIds=${alert.status.silencedBy.join(',')}`}
|
|
className={styles.button}
|
|
icon={'bell'}
|
|
size={'sm'}
|
|
>
|
|
Manage silences
|
|
</LinkButton>
|
|
)}
|
|
{alert.status.state === AlertState.Active && (
|
|
<LinkButton
|
|
href={makeLabelBasedSilenceLink(alertManagerSourceName, alert.labels)}
|
|
className={styles.button}
|
|
icon={'bell-slash'}
|
|
size={'sm'}
|
|
>
|
|
Silence
|
|
</LinkButton>
|
|
)}
|
|
</Authorize>
|
|
<Authorize
|
|
actions={isExternalAM ? [AccessControlAction.DataSourcesExplore] : [AccessControlAction.AlertingInstanceRead]}
|
|
>
|
|
{alert.generatorURL && (
|
|
<LinkButton className={styles.button} href={alert.generatorURL} icon={'chart-line'} size={'sm'}>
|
|
See source
|
|
</LinkButton>
|
|
)}
|
|
</Authorize>
|
|
</div>
|
|
{Object.entries(alert.annotations).map(([annotationKey, annotationValue]) => (
|
|
<AnnotationDetailsField key={annotationKey} annotationKey={annotationKey} value={annotationValue} />
|
|
))}
|
|
<div className={styles.receivers}>
|
|
Receivers:{' '}
|
|
{alert.receivers
|
|
.map(({ name }) => name)
|
|
.filter((name) => !!name)
|
|
.join(', ')}
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
const getStyles = (theme: GrafanaTheme2) => ({
|
|
button: css`
|
|
& + & {
|
|
margin-left: ${theme.spacing(1)};
|
|
}
|
|
`,
|
|
actionsRow: css`
|
|
padding: ${theme.spacing(2, 0)} !important;
|
|
border-bottom: 1px solid ${theme.colors.border.medium};
|
|
`,
|
|
receivers: css`
|
|
padding: ${theme.spacing(1, 0)};
|
|
`,
|
|
});
|