Added validation for existent contact point for grafana alerting (#2829)

# What this PR does

- Sort of fixed the stalling issue of the `counters` request - now just
the very first request to `counters` would be slow, everything else just
uses existing data we already fetched
- Added validation if contact point is already defined for the selected
datasource for alerting

## Which issue(s) this PR fixes

## Checklist

- [ ] Unit, integration, and e2e (if applicable) tests updated
- [ ] Documentation added (or `pr:no public docs` PR label added if not
required)
- [ ] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
This commit is contained in:
Rares Mardare 2023-08-18 16:51:54 +03:00 committed by GitHub
parent 8a946364fe
commit 10e8270b40
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 23 deletions

View file

@ -63,6 +63,13 @@ const IntegrationForm = observer((props: IntegrationFormProps) => {
const [showNewIntegrationForm, setShowNewIntegrationForm] = useState(false);
const [selectedOption, setSelectedOption] = useState<AlertReceiveChannelOption>(undefined);
const [showIntegrarionsListDrawer, setShowIntegrarionsListDrawer] = useState(id === 'new');
const [allContactPoints, setAllContactPoints] = useState(undefined);
useEffect(() => {
(async function () {
setAllContactPoints(await alertReceiveChannelStore.getGrafanaAlertingContactPoints());
})();
}, []);
const data =
id === 'new'
@ -154,6 +161,20 @@ const IntegrationForm = observer((props: IntegrationFormProps) => {
);
function handleSubmit(data) {
const { alert_manager, contact_point, is_existing: isExisting } = data;
const matchingAlertManager = allContactPoints.find((cp) => cp.uid === alert_manager);
const hasContactPointInput = alert_manager && contact_point;
if (
!isExisting &&
hasContactPointInput &&
matchingAlertManager?.contact_points.find((cp) => cp === contact_point)
) {
openErrorNotification('A contact point already exists for this data source');
return;
}
(id === 'new' ? createNewIntegration() : alertReceiveChannelStore.update(id, data)).then(() => {
onHide();
onUpdate();
@ -175,8 +196,8 @@ const IntegrationForm = observer((props: IntegrationFormProps) => {
? alertReceiveChannelStore.connectContactPoint(response.id, data.alert_manager, data.contact_point)
: alertReceiveChannelStore.createContactPoint(response.id, data.alert_manager, data.contact_point)
)
.then(() => pushHistory(response.id))
.catch(onCatch);
.catch(onCatch)
.finally(() => pushHistory(response.id));
})
.catch(onCatch);

View file

@ -13,7 +13,7 @@ import {
Alert,
} from '@grafana/ui';
import cn from 'classnames/bind';
import { get } from 'lodash-es';
import { get, noop } from 'lodash-es';
import { observer } from 'mobx-react';
import CopyToClipboard from 'react-copy-to-clipboard';
import Emoji from 'react-emoji-render';
@ -106,27 +106,13 @@ class Integration extends React.Component<IntegrationProps, IntegrationState> {
}
async componentDidMount() {
const {
match: {
params: { id },
},
query,
} = this.props;
const {
store,
store: { alertReceiveChannelStore },
} = this.props;
const { query } = this.props;
if (query?.template) {
this.openEditTemplateModal(query.template, query.routeId && query.routeId);
}
await Promise.all([
this.loadIntegration(),
IntegrationHelper.fetchChatOps(store),
alertReceiveChannelStore.updateTemplates(id),
]);
await this.loadIntegration();
}
render() {
@ -416,7 +402,7 @@ class Integration extends React.Component<IntegrationProps, IntegrationState> {
Grouping:
</Text>
<Text type="primary">
{IntegrationHelper.truncateLine(templates['grouping_id_template'] || '')}
{IntegrationHelper.truncateLine(templates?.['grouping_id_template'] || '')}
</Text>
</div>
@ -671,6 +657,7 @@ class Integration extends React.Component<IntegrationProps, IntegrationState> {
async loadIntegration() {
const {
store,
store: { alertReceiveChannelStore },
match: {
params: { id },
@ -685,17 +672,21 @@ class Integration extends React.Component<IntegrationProps, IntegrationState> {
promises.push(alertReceiveChannelStore.loadItem(id));
}
if (!alertReceiveChannelStore.counters?.length) {
if (!alertReceiveChannelStore.counters[id]) {
promises.push(alertReceiveChannelStore.updateCounters());
}
if (!alertReceiveChannelStore.channelFilterIds[id]) {
promises.push(await alertReceiveChannelStore.updateChannelFilters(id));
promises.push(alertReceiveChannelStore.updateChannelFilters(id));
}
promises.push(alertReceiveChannelStore.updateTemplates(id));
promises.push(IntegrationHelper.fetchChatOps(store));
// skip checking for grafana alerting so that we don't wait for the first request to complete
// at the cost of getting a failed network request for all other types other than alerting
promises.push(alertReceiveChannelStore.updateConnectedContactPoints(id));
promises.push(alertReceiveChannelStore.updateConnectedContactPoints(id).catch(noop));
await Promise.all(promises)
.catch(() => {