Alerting: Dedicated permission for Template testing API (#115032)
This commit is contained in:
+1
@@ -238,6 +238,7 @@ For more information on Cloud Access Policies and how to use them, see [Access p
|
||||
| `alert.notifications.templates:read` | None | Read templates. |
|
||||
| `alert.notifications.templates:write` | None | Create new or update existing templates. |
|
||||
| `alert.notifications.templates:delete` | None | Delete existing templates. |
|
||||
| `alert.notifications.templates.test:write` | None | Test templates with custom payloads (preview and payload editor functionality). |
|
||||
| `alert.notifications.routes:read` | None | Read notification policies. |
|
||||
| `alert.notifications.routes:write` | None | Create new, update or delete notification policies |
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ Grafana Alerting has the following permissions.
|
||||
| `alert.notifications.templates:read` | n/a | Read templates. |
|
||||
| `alert.notifications.templates:write` | n/a | Create new or update existing templates. |
|
||||
| `alert.notifications.templates:delete` | n/a | Delete existing templates. |
|
||||
| `alert.notifications.templates.test:write` | n/a | Test templates with custom payloads (preview and payload editor functionality). |
|
||||
| `alert.notifications.routes:read` | n/a | Read notification policies. |
|
||||
| `alert.notifications.routes:write` | n/a | Create new, update and update notification policies. |
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ Details of the fixed roles and the access they provide for Grafana Alerting are
|
||||
| Contact Point Creator: `fixed:alerting.receivers:creator` | `alert.notifications.receivers:create` | Create a new contact point. The user is automatically granted full access to the created contact point. |
|
||||
| Contact Point Writer: `fixed:alerting.receivers:writer` | `alert.notifications.receivers:read`, `alert.notifications.receivers:write`, `alert.notifications.receivers:delete` for scope `receivers:*` and <br> `alert.notifications.receivers:create` | Create a new contact point and manage all existing contact points. |
|
||||
| Templates Reader: `fixed:alerting.templates:reader` | `alert.notifications.templates:read` | Read all notification templates. |
|
||||
| Templates Writer: `fixed:alerting.templates:writer` | `alert.notifications.templates:read`, `alert.notifications.templates:write`, `alert.notifications.templates:delete` | Create new and manage existing notification templates. |
|
||||
| Templates Writer: `fixed:alerting.templates:writer` | `alert.notifications.templates:read`, `alert.notifications.templates:write`, `alert.notifications.templates:delete`, `alert.notifications.templates.test:write` | Create new and manage existing notification templates. Test templates with custom payloads. |
|
||||
| Time Intervals Reader: `fixed:alerting.time-intervals:reader` | `alert.notifications.time-intervals:read` | Read all time intervals. |
|
||||
| Time Intervals Writer: `fixed:alerting.time-intervals:writer` | `alert.notifications.time-intervals:read`, `alert.notifications.time-intervals:write`, `alert.notifications.time-intervals:delete` | Create new and manage existing time intervals. |
|
||||
| Notification Policies Reader: `fixed:alerting.routes:reader` | `alert.notifications.routes:read` | Read all time intervals. |
|
||||
|
||||
@@ -447,6 +447,7 @@ const (
|
||||
ActionAlertingNotificationsTemplatesRead = "alert.notifications.templates:read"
|
||||
ActionAlertingNotificationsTemplatesWrite = "alert.notifications.templates:write"
|
||||
ActionAlertingNotificationsTemplatesDelete = "alert.notifications.templates:delete"
|
||||
ActionAlertingNotificationsTemplatesTest = "alert.notifications.templates.test:write"
|
||||
|
||||
// Alerting notifications time interval actions
|
||||
ActionAlertingNotificationsTimeIntervalsRead = "alert.notifications.time-intervals:read"
|
||||
|
||||
@@ -173,6 +173,7 @@ var (
|
||||
Permissions: accesscontrol.ConcatPermissions(templatesReaderRole.Role.Permissions, []accesscontrol.Permission{
|
||||
{Action: accesscontrol.ActionAlertingNotificationsTemplatesWrite},
|
||||
{Action: accesscontrol.ActionAlertingNotificationsTemplatesDelete},
|
||||
{Action: accesscontrol.ActionAlertingNotificationsTemplatesTest},
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ func (api *API) authorize(method, path string) web.Handler {
|
||||
case http.MethodPost + "/api/alertmanager/grafana/config/api/v1/templates/test":
|
||||
eval = ac.EvalAny(
|
||||
ac.EvalPermission(ac.ActionAlertingNotificationsWrite),
|
||||
ac.EvalPermission(ac.ActionAlertingNotificationsTemplatesRead),
|
||||
ac.EvalPermission(ac.ActionAlertingNotificationsTemplatesTest),
|
||||
)
|
||||
|
||||
// External Alertmanager Paths
|
||||
|
||||
@@ -26,8 +26,10 @@ import {
|
||||
useStyles2,
|
||||
} from '@grafana/ui';
|
||||
import { useAppNotification } from 'app/core/copy/appNotification';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { ActiveTab as ContactPointsActiveTabs } from 'app/features/alerting/unified/components/contact-points/ContactPoints';
|
||||
import { TestTemplateAlert } from 'app/plugins/datasource/alertmanager/types';
|
||||
import { AccessControlAction } from 'app/types/accessControl';
|
||||
|
||||
import { AITemplateButtonComponent } from '../../enterprise-components/AI/AIGenTemplateButton/addAITemplateButton';
|
||||
import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';
|
||||
@@ -100,6 +102,16 @@ export const TemplateForm = ({ originalTemplate, prefill, alertmanager }: Props)
|
||||
const formRef = useRef<HTMLFormElement>(null);
|
||||
const isGrafanaAlertManager = alertmanager === GRAFANA_RULES_SOURCE_NAME;
|
||||
|
||||
// Check if user has permission to test templates
|
||||
const canTestTemplates =
|
||||
contextSrv.hasPermission(AccessControlAction.AlertingNotificationsTemplatesTest) ||
|
||||
contextSrv.hasPermission(AccessControlAction.AlertingNotificationsWrite);
|
||||
|
||||
// Only show preview and payload panels if both conditions are met:
|
||||
// 1. It's a Grafana Alertmanager
|
||||
// 2. User has the test permission
|
||||
const showPreviewAndPayload = isGrafanaAlertManager && canTestTemplates;
|
||||
|
||||
const error = updateTemplateError ?? createTemplateError;
|
||||
|
||||
const [cheatsheetOpened, toggleCheatsheetOpened] = useToggle(false);
|
||||
@@ -118,16 +130,16 @@ export const TemplateForm = ({ originalTemplate, prefill, alertmanager }: Props)
|
||||
// splitter for template and payload editor
|
||||
const columnSplitter = useSplitter({
|
||||
direction: 'column',
|
||||
// if Grafana Alertmanager, split 50/50, otherwise 100/0 because there is no payload editor
|
||||
initialSize: isGrafanaAlertManager ? 0.5 : 1,
|
||||
// if showing preview/payload panels, split 50/50, otherwise 100/0 because there is no payload editor
|
||||
initialSize: showPreviewAndPayload ? 0.5 : 1,
|
||||
dragPosition: 'middle',
|
||||
});
|
||||
|
||||
// splitter for template editor and preview
|
||||
const rowSplitter = useSplitter({
|
||||
direction: 'row',
|
||||
// if Grafana Alertmanager, split 60/40, otherwise 100/0 because there is no preview
|
||||
initialSize: isGrafanaAlertManager ? 0.6 : 1,
|
||||
// if showing preview/payload panels, split 60/40, otherwise 100/0 because there is no preview
|
||||
initialSize: showPreviewAndPayload ? 0.6 : 1,
|
||||
dragPosition: 'middle',
|
||||
});
|
||||
|
||||
@@ -319,8 +331,8 @@ export const TemplateForm = ({ originalTemplate, prefill, alertmanager }: Props)
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
{/* payload editor – only available for Grafana Alertmanager */}
|
||||
{isGrafanaAlertManager && (
|
||||
{/* payload editor – only shown if user has test permission */}
|
||||
{showPreviewAndPayload && (
|
||||
<>
|
||||
<div {...columnSplitter.splitterProps} />
|
||||
<div {...columnSplitter.secondaryProps}>
|
||||
@@ -345,8 +357,8 @@ export const TemplateForm = ({ originalTemplate, prefill, alertmanager }: Props)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/* preview column – full height and half-width */}
|
||||
{isGrafanaAlertManager && (
|
||||
{/* preview column – only shown if user has test permission */}
|
||||
{showPreviewAndPayload && (
|
||||
<div {...rowSplitter.secondaryProps}>
|
||||
<div {...rowSplitter.splitterProps} />
|
||||
<TemplatePreview
|
||||
|
||||
@@ -156,6 +156,7 @@ export enum AccessControlAction {
|
||||
AlertingTemplatesRead = 'alert.notifications.templates:read',
|
||||
AlertingTemplatesWrite = 'alert.notifications.templates:write',
|
||||
AlertingTemplatesDelete = 'alert.notifications.templates:delete',
|
||||
AlertingNotificationsTemplatesTest = 'alert.notifications.templates.test:write',
|
||||
|
||||
// Alerting enrichments actions
|
||||
AlertingEnrichmentsRead = 'alert.enrichments:read',
|
||||
|
||||
Reference in New Issue
Block a user