Alerting: Enable "dot-notation" rule (#91497)

This commit is contained in:
Tom Ratcliffe
2024-08-05 12:06:17 +01:00
committed by GitHub
parent 500ae2ff1e
commit 734af2ea9f
19 changed files with 44 additions and 43 deletions
+1
View File
@@ -1,6 +1,7 @@
{
"plugins": ["testing-library"],
"rules": {
"dot-notation": "error",
"prefer-const": "error",
"react/no-unused-prop-types": "error",
},
@@ -392,11 +392,11 @@ interface QueryParamValues {
function getActiveTabFromUrl(queryParams: UrlQueryMap): QueryParamValues {
let tab = ActiveTab.NotificationPolicies; // default tab
if (queryParams['tab'] === ActiveTab.NotificationPolicies) {
if (queryParams.tab === ActiveTab.NotificationPolicies) {
tab = ActiveTab.NotificationPolicies;
}
if (queryParams['tab'] === ActiveTab.MuteTimings) {
if (queryParams.tab === ActiveTab.MuteTimings) {
tab = ActiveTab.MuteTimings;
}
@@ -760,7 +760,7 @@ describe('RuleList', () => {
{ dataSourceName: testDatasources.prom.name, apiVersion: 'legacy' },
'super namespace',
{
...someRulerRules['namespace1'][0],
...someRulerRules.namespace1[0],
name: 'super group',
interval: '5m',
}
@@ -769,7 +769,7 @@ describe('RuleList', () => {
2,
{ dataSourceName: testDatasources.prom.name, apiVersion: 'legacy' },
'super namespace',
someRulerRules['namespace1'][1]
someRulerRules.namespace1[1]
);
expect(mocks.api.deleteNamespace).toHaveBeenLastCalledWith(
{ dataSourceName: testDatasources.prom.name, apiVersion: 'legacy' },
@@ -799,7 +799,7 @@ describe('RuleList', () => {
{ dataSourceName: testDatasources.prom.name, apiVersion: 'legacy' },
'namespace1',
{
...someRulerRules['namespace1'][0],
...someRulerRules.namespace1[0],
name: 'super group',
interval: '5m',
}
@@ -830,7 +830,7 @@ describe('RuleList', () => {
{ dataSourceName: testDatasources.prom.name, apiVersion: 'legacy' },
'namespace1',
{
...someRulerRules['namespace1'][0],
...someRulerRules.namespace1[0],
interval: '5m',
}
);
@@ -94,8 +94,8 @@ describe('getGroupedByStateAndSeriesCount', () => {
const { groupedByState, seriesCount } = getGroupedByStateAndSeriesCount(series);
expect(groupedByState['firing']).toEqual([series[0], series[3]]);
expect(groupedByState['inactive']).toEqual([series[2]]);
expect(groupedByState.firing).toEqual([series[0], series[3]]);
expect(groupedByState.inactive).toEqual([series[2]]);
expect(seriesCount).toEqual(3);
});
@@ -119,8 +119,8 @@ describe('getGroupedByStateAndSeriesCount', () => {
const { groupedByState, seriesCount } = getGroupedByStateAndSeriesCount(series);
expect(groupedByState['firing']).toEqual([]);
expect(groupedByState['inactive']).toEqual([]);
expect(groupedByState.firing).toEqual([]);
expect(groupedByState.inactive).toEqual([]);
expect(seriesCount).toEqual(0);
});
@@ -133,8 +133,8 @@ describe('getGroupedByStateAndSeriesCount', () => {
const { groupedByState, seriesCount } = getGroupedByStateAndSeriesCount(series);
expect(groupedByState['firing']).toEqual([]);
expect(groupedByState['inactive']).toEqual(series);
expect(groupedByState.firing).toEqual([]);
expect(groupedByState.inactive).toEqual(series);
expect(seriesCount).toEqual(series.length);
});
@@ -147,8 +147,8 @@ describe('getGroupedByStateAndSeriesCount', () => {
const { groupedByState, seriesCount } = getGroupedByStateAndSeriesCount(series);
expect(groupedByState['firing']).toEqual(series);
expect(groupedByState['inactive']).toEqual([]);
expect(groupedByState.firing).toEqual(series);
expect(groupedByState.inactive).toEqual([]);
expect(seriesCount).toEqual(series.length);
});
});
@@ -56,10 +56,10 @@ export function AlertInstanceModalSelector({
const rules: Record<string, AlertmanagerAlert[]> = {};
if (!loading && result) {
result.forEach((instance) => {
if (!rules[instance.labels['alertname']]) {
rules[instance.labels['alertname']] = [];
if (!rules[instance.labels.alertname]) {
rules[instance.labels.alertname] = [];
}
rules[instance.labels['alertname']].push(instance);
rules[instance.labels.alertname].push(instance);
});
}
return rules;
@@ -106,7 +106,7 @@ export function AlertInstanceModalSelector({
<div className={cx(styles.ruleTitle, styles.rowButtonTitle)}>{ruleName}</div>
<div className={styles.alertFolder}>
<>
<Icon name="folder" /> {filteredRules[ruleName][0].labels['grafana_folder'] ?? ''}
<Icon name="folder" /> {filteredRules[ruleName][0].labels.grafana_folder ?? ''}
</>
</div>
</button>
@@ -151,7 +151,7 @@ export function AlertInstanceModalSelector({
})}
onClick={handleSelectInstances}
>
<div className={styles.rowButtonTitle} title={alert.labels['alertname']}>
<div className={styles.rowButtonTitle} title={alert.labels.alertname}>
<Tooltip placement="bottom" content={<pre>{JSON.stringify(alert, null, 2)}</pre>} theme={'info'}>
<div>
{tags.map((tag, index) => (
@@ -83,7 +83,7 @@ export function ChannelSubForm<R extends ChannelValues>({
name === fieldName('settings.integration_type') &&
value === OnCallIntegrationType.ExistingIntegration
) {
setValue(fieldName('settings.url'), initialValues.settings['url']);
setValue(fieldName('settings.url'), initialValues.settings.url);
}
});
@@ -58,7 +58,7 @@ describe('useOnCallIntegration', () => {
OnCallIntegrationType.ExistingIntegration
);
expect(receiverConfig.settings[OnCallIntegrationSetting.IntegrationName]).toBeUndefined();
expect(receiverConfig.settings['url']).toBe('https://oncall-endpoint.example.com');
expect(receiverConfig.settings.url).toBe('https://oncall-endpoint.example.com');
});
it('createOnCallIntegrations should provide integration name and url validators', async () => {
@@ -153,7 +153,7 @@ export function useOnCallIntegration() {
verbal_name: c.settings[OnCallIntegrationSetting.IntegrationName],
}).unwrap();
c.settings['url'] = newIntegration.integration_url;
c.settings.url = newIntegration.integration_url;
});
await Promise.all(createNewOnCallIntegrationJobs);
@@ -236,7 +236,7 @@ export function FolderAndGroup({
getOptionLabel={(option: SelectableValue<string>) => (
<div>
<span>{option.label}</span>
{option['isProvisioned'] && (
{option.isProvisioned && (
<>
{' '}
<ProvisioningBadge />
@@ -72,7 +72,7 @@ export const AlertRuleForm = ({ existing, prefill }: Props) => {
const ruleType = translateRouteParamToRuleType(routeParams.type);
const uidFromParams = routeParams.id;
const returnTo = !queryParams['returnTo'] ? '/alerting/list' : String(queryParams['returnTo']);
const returnTo = !queryParams.returnTo ? '/alerting/list' : String(queryParams.returnTo);
const [showDeleteModal, setShowDeleteModal] = useState<boolean>(false);
const defaultValues: RuleFormValues = useMemo(() => {
@@ -84,8 +84,8 @@ export const AlertRuleForm = ({ existing, prefill }: Props) => {
return formValuesFromPrefill(prefill);
}
if (typeof queryParams['defaults'] === 'string') {
return formValuesFromQueryParams(queryParams['defaults'], ruleType);
if (typeof queryParams.defaults === 'string') {
return formValuesFromQueryParams(queryParams.defaults, ruleType);
}
return {
@@ -43,7 +43,7 @@ export function ModifyExportRuleForm({ ruleForm, alertUid }: ModifyExportRuleFor
const existing = Boolean(ruleForm); // always should be true
const notifyApp = useAppNotification();
const returnTo = !queryParams['returnTo'] ? '/alerting/list' : String(queryParams['returnTo']);
const returnTo = !queryParams.returnTo ? '/alerting/list' : String(queryParams.returnTo);
const [exportData, setExportData] = useState<RuleFormValues | undefined>(undefined);
@@ -45,7 +45,7 @@ export const EvaluationGroupWithRules = ({ group, rulesSource }: EvaluationGroup
evaluationInterval={group.interval}
instancesCount={isAlertingPromRule ? size(promRule.alerts) : undefined}
href={createViewLink(rulesSource, rule)}
summary={annotations?.['summary']}
summary={annotations?.summary}
/>
);
}
@@ -81,7 +81,7 @@ export const EvaluationGroupWithRules = ({ group, rulesSource }: EvaluationGroup
evaluationInterval={group.interval}
instancesCount={isAlertingPromRule ? size(promRule.alerts) : undefined}
href={createViewLink(rulesSource, rule)}
summary={rule.annotations?.['summary']}
summary={rule.annotations?.summary}
isProvisioned={Boolean(rulerRule.grafana_alert.provenance)}
contactPoint={contactPoint}
/>
@@ -46,7 +46,7 @@ const RuleList = withErrorBoundary(
const [queryParams] = useQueryParams();
const { filterState, hasActiveFilters } = useRulesFilter();
const queryParamView = queryParams['view'] as keyof typeof VIEWS;
const queryParamView = queryParams.view as keyof typeof VIEWS;
const view = VIEWS[queryParamView] ? queryParamView : 'groups';
const ViewComponent = VIEWS[view];
@@ -265,7 +265,7 @@ export const isErrorHealth = (health?: RuleHealth) => health === 'error' || heal
export function useActiveTab(): [ActiveTab, (tab: ActiveTab) => void] {
const [queryParams, setQueryParams] = useQueryParams();
const tabFromQuery = queryParams['tab'];
const tabFromQuery = queryParams.tab;
const activeTab = isValidTab(tabFromQuery) ? tabFromQuery : ActiveTab.Query;
@@ -40,7 +40,7 @@ export const GrafanaRules = ({ namespaces, expandAll }: Props) => {
const loading = prom.loading || ruler.loading;
const hasResult = !!prom.result || !!ruler.result;
const wantsListView = queryParams['view'] === 'list';
const wantsListView = queryParams.view === 'list';
const namespacesFormat = wantsListView ? flattenGrafanaManagedRules(namespaces) : namespaces;
const groupsWithNamespaces = useCombinedGroupNamespace(namespacesFormat);
@@ -232,7 +232,7 @@ function AlertRuleName({ labels, ruleUID }: AlertRuleNameProps) {
const styles = useStyles2(getStyles);
const { pathname, search } = useLocation();
const returnTo = `${pathname}${search}`;
const alertRuleName = labels['alertname'];
const alertRuleName = labels.alertname;
if (!ruleUID) {
return (
<Text>
@@ -288,11 +288,11 @@ export function calculateRuleTotals(rule: Pick<AlertingRule, 'alerts' | 'totals'
}
return {
alerting: result[AlertInstanceTotalState.Alerting] || result['firing'],
alerting: result[AlertInstanceTotalState.Alerting] || result.firing,
pending: result[AlertInstanceTotalState.Pending],
inactive: result[AlertInstanceTotalState.Normal],
nodata: result[AlertInstanceTotalState.NoData],
error: result[AlertInstanceTotalState.Error] || result['err'] || undefined, // Prometheus uses "err" instead of "error"
error: result[AlertInstanceTotalState.Error] || result.err || undefined, // Prometheus uses "err" instead of "error"
};
}
@@ -75,11 +75,11 @@ export function arrayToRecord(items: Array<{ key: string; value: string }>): Rec
}
export const getFiltersFromUrlParams = (queryParams: UrlQueryMap): FilterState => {
const queryString = queryParams['queryString'] === undefined ? undefined : String(queryParams['queryString']);
const alertState = queryParams['alertState'] === undefined ? undefined : String(queryParams['alertState']);
const dataSource = queryParams['dataSource'] === undefined ? undefined : String(queryParams['dataSource']);
const ruleType = queryParams['ruleType'] === undefined ? undefined : String(queryParams['ruleType']);
const groupBy = queryParams['groupBy'] === undefined ? undefined : String(queryParams['groupBy']).split(',');
const queryString = queryParams.queryString === undefined ? undefined : String(queryParams.queryString);
const alertState = queryParams.alertState === undefined ? undefined : String(queryParams.alertState);
const dataSource = queryParams.dataSource === undefined ? undefined : String(queryParams.dataSource);
const ruleType = queryParams.ruleType === undefined ? undefined : String(queryParams.ruleType);
const groupBy = queryParams.groupBy === undefined ? undefined : String(queryParams.groupBy).split(',');
return { queryString, alertState, dataSource, groupBy, ruleType };
};
@@ -91,8 +91,8 @@ export const getNotificationPoliciesFilters = (searchParams: URLSearchParams) =>
};
export const getSilenceFiltersFromUrlParams = (queryParams: UrlQueryMap): SilenceFilterState => {
const queryString = queryParams['queryString'] === undefined ? undefined : String(queryParams['queryString']);
const silenceState = queryParams['silenceState'] === undefined ? undefined : String(queryParams['silenceState']);
const queryString = queryParams.queryString === undefined ? undefined : String(queryParams.queryString);
const silenceState = queryParams.silenceState === undefined ? undefined : String(queryParams.silenceState);
return { queryString, silenceState };
};
@@ -148,7 +148,7 @@ export function getRulePluginOrigin(rule: CombinedRule): RulePluginOrigin | unde
return undefined;
}
const pluginId = match.groups['pluginId'];
const pluginId = match.groups.pluginId;
const pluginInstalled = isPluginInstalled(pluginId);
if (!pluginInstalled) {