Alerting: Add FGAC to alerts tab in panel editor (#47732)

* add FGAC for alert panel tab

* add test for panel tabs

* Refactor condition

Co-authored-by: Konrad Lalik <konrad.lalik@grafana.com>
This commit is contained in:
Nathan Rodman 2022-04-14 05:19:15 -07:00 committed by GitHub
parent 90892050d0
commit c63086822d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 6 deletions

View File

@ -7,6 +7,8 @@ import { NewRuleFromPanelButton } from './components/panel-alerts-tab/NewRuleFro
import { RulesTable } from './components/rules/RulesTable';
import { usePanelCombinedRules } from './hooks/usePanelCombinedRules';
import { selectors } from '@grafana/e2e-selectors';
import { getRulesPermissions } from './utils/access-control';
import { contextSrv } from 'app/core/services/context_srv';
interface Props {
dashboard: DashboardModel;
@ -20,6 +22,8 @@ export const PanelAlertTabContent: FC<Props> = ({ dashboard, panel }) => {
panel,
poll: true,
});
const permissions = getRulesPermissions('grafana');
const canCreateRules = contextSrv.hasPermission(permissions.create);
const alert = errors.length ? (
<Alert title="Errors loading rules" severity="error">
@ -44,7 +48,7 @@ export const PanelAlertTabContent: FC<Props> = ({ dashboard, panel }) => {
<div className={styles.innerWrapper}>
{alert}
<RulesTable rules={rules} />
{!!dashboard.meta.canSave && (
{!!dashboard.meta.canSave && canCreateRules && (
<NewRuleFromPanelButton className={styles.newButton} panel={panel} dashboard={dashboard} />
)}
</div>
@ -58,7 +62,7 @@ export const PanelAlertTabContent: FC<Props> = ({ dashboard, panel }) => {
{!!dashboard.uid && (
<>
<p>There are no alert rules linked to this panel.</p>
{!!dashboard.meta.canSave && <NewRuleFromPanelButton panel={panel} dashboard={dashboard} />}
{!!dashboard.meta.canSave && canCreateRules && <NewRuleFromPanelButton panel={panel} dashboard={dashboard} />}
</>
)}
{!dashboard.uid && !!dashboard.meta.canSave && (

View File

@ -2,6 +2,13 @@ import { getPanelEditorTabs } from './selectors';
import { PanelPlugin } from '@grafana/data';
import { PanelEditorTabId } from '../types';
import { updateConfig } from '../../../../../core/config';
import { contextSrv } from 'app/core/services/context_srv';
jest.mock('app/core/services/context_srv');
const mocks = {
contextSrv: jest.mocked(contextSrv),
};
describe('getPanelEditorTabs selector', () => {
it('return no tabs when no plugin provided', () => {
@ -79,5 +86,37 @@ describe('getPanelEditorTabs selector', () => {
expect(tabs[1].id).toEqual(PanelEditorTabId.Transform);
});
});
describe('with unified alerting enabled', () => {
beforeAll(() => {
updateConfig({ unifiedAlertingEnabled: true });
});
it('shows the alert tab for users with read permission', () => {
mocks.contextSrv.hasPermission.mockReturnValue(true);
const tabs = getPanelEditorTabs(undefined, {
meta: {
id: 'graph',
},
} as PanelPlugin);
expect(tabs.length).toEqual(3);
expect(tabs[2].id).toEqual(PanelEditorTabId.Alert);
});
it('hides the alert tab for users with read permission', () => {
mocks.contextSrv.hasPermission.mockReturnValue(false);
const tabs = getPanelEditorTabs(undefined, {
meta: {
id: 'graph',
},
} as PanelPlugin);
expect(tabs.length).toEqual(2);
expect(tabs[1].id).toEqual(PanelEditorTabId.Transform);
});
});
});
});

View File

@ -2,6 +2,9 @@ import memoizeOne from 'memoize-one';
import { PanelPlugin } from '@grafana/data';
import { PanelEditorTab, PanelEditorTabId } from '../types';
import { getConfig } from 'app/core/config';
import { getRulesPermissions } from 'app/features/alerting/unified/utils/access-control';
import { contextSrv } from 'app/core/services/context_srv';
import { GRAFANA_RULES_SOURCE_NAME } from 'app/features/alerting/unified/utils/datasource';
export const getPanelEditorTabs = memoizeOne((tab?: string, plugin?: PanelPlugin) => {
const tabs: PanelEditorTab[] = [];
@ -34,10 +37,14 @@ export const getPanelEditorTabs = memoizeOne((tab?: string, plugin?: PanelPlugin
});
}
if (
((getConfig().alertingEnabled || getConfig().unifiedAlertingEnabled) && plugin.meta.id === 'graph') ||
plugin.meta.id === 'timeseries'
) {
const { alertingEnabled, unifiedAlertingEnabled } = getConfig();
const hasRuleReadPermissions = contextSrv.hasPermission(getRulesPermissions(GRAFANA_RULES_SOURCE_NAME).read);
const isAlertingAvailable = alertingEnabled || (unifiedAlertingEnabled && hasRuleReadPermissions);
const isGraph = plugin.meta.id === 'graph';
const isTimeseries = plugin.meta.id === 'timeseries';
if ((isAlertingAvailable && isGraph) || isTimeseries) {
tabs.push({
id: PanelEditorTabId.Alert,
text: 'Alert',