Alerting: Allow created by to be manually set when there's no creator for silences (#55952)

* Alerting: Allow created by to be manually set when there's no creator

Grafana has a mode that allows unauthenticated interaction, typically the created by field of a silence is inferred from the current logged user. When this is not present, the field is left black and thus the silence creation fails.

This allows us to set the created by when we is not possible to infer it from the current user.

* Show created by input field only if user is not logged

* Add test for new logic with createdBy input field

Co-authored-by: Sonia Aguilar <soniaaguilarpeiron@gmail.com>
This commit is contained in:
gotjosh 2022-10-03 09:56:27 +01:00 committed by GitHub
parent fca252e7dc
commit 501e921b2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 1 deletions

View File

@ -6,7 +6,7 @@ import { Router } from 'react-router-dom';
import { byLabelText, byPlaceholderText, byRole, byTestId, byText } from 'testing-library-selector';
import { dateTime } from '@grafana/data';
import { locationService, setDataSourceSrv } from '@grafana/runtime';
import { locationService, setDataSourceSrv, config } from '@grafana/runtime';
import { contextSrv } from 'app/core/services/context_srv';
import { AlertState, MatcherOperator } from 'app/plugins/datasource/alertmanager/types';
import { configureStore } from 'app/store/configureStore';
@ -70,6 +70,7 @@ const ui = {
matcherOperator: (operator: MatcherOperator) => byText(operator, { exact: true }),
addMatcherButton: byRole('button', { name: 'Add matcher' }),
submit: byText('Submit'),
createdBy: byText(/created by \*/i),
},
};
@ -112,6 +113,11 @@ const resetMocks = () => {
mocks.contextSrv.hasAccess.mockImplementation(() => true);
};
const setUserLogged = (isLogged: boolean) => {
config.bootData.user.isSignedIn = isLogged;
config.bootData.user.name = isLogged ? 'admin' : '';
};
describe('Silences', () => {
beforeAll(resetMocks);
afterEach(resetMocks);
@ -210,9 +216,19 @@ describe('Silence edit', () => {
afterEach(resetMocks);
beforeEach(() => {
setUserLogged(true);
setDataSourceSrv(new MockDataSourceSrv(dataSources));
});
it('Should not render createdBy if user is logged in and has a name', async () => {
renderSilences(baseUrlPath);
await waitFor(() => expect(ui.editor.createdBy.query()).not.toBeInTheDocument());
});
it('Should render createdBy if user is not logged or has no name', async () => {
setUserLogged(false);
renderSilences(baseUrlPath);
await waitFor(() => expect(ui.editor.createdBy.get()).toBeInTheDocument());
});
it(
'prefills the matchers field with matchers params',
async () => {

View File

@ -164,6 +164,7 @@ export const SilencesEditor: FC<Props> = ({ silence, alertManagerSourceName }) =
700,
[clearErrors, duration, endsAt, prevDuration, setValue, startsAt]
);
const userLogged = Boolean(config.bootData.user.isSignedIn && config.bootData.user.name);
return (
<FormProvider {...formAPI}>
@ -206,6 +207,20 @@ export const SilencesEditor: FC<Props> = ({ silence, alertManagerSourceName }) =
placeholder="Details about the silence"
/>
</Field>
{!userLogged && (
<Field
className={cx(styles.field, styles.createdBy)}
label="Created By"
required
error={formState.errors.createdBy?.message}
invalid={!!formState.errors.createdBy}
>
<Input
{...register('createdBy', { required: { value: true, message: 'Required.' } })}
placeholder="Who's creating the silence"
/>
</Field>
)}
<MatchedSilencedRules />
</FieldSet>
<div className={styles.flexRow}>