Skip to content

Commit 23541c4

Browse files
upcoming: [DI-28506] - Filter linode resources based on associated aclp alerts (#13163)
* upcoming: [DI-28506] - filter linode resources based on alerts * upcoming: [DI-28506] - Update comment * upcoming: [DI-28506] - move utils from shared to alerting specific file * upcoming: [DI-28506] - Update mock * upcoming: [DI-28506] - Add changeset * upcoming: [DI-28506] - add copilot suggestion
1 parent 45b2877 commit 23541c4

File tree

7 files changed

+81
-10
lines changed

7 files changed

+81
-10
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/manager": Upcoming Features
3+
---
4+
5+
CloudPulse-Alerts: Filter linode resources based on associated aclp alerts ([#13163](https://github.com/linode/manager/pull/13163))

packages/manager/src/features/CloudPulse/Alerts/AlertRegions/AlertRegions.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
import { AlertListNoticeMessages } from '../Utils/AlertListNoticeMessages';
1616
import { scrollToElement } from '../Utils/AlertResourceUtils';
1717
import { AlertSelectedInfoNotice } from '../Utils/AlertSelectedInfoNotice';
18+
import { getFilterFn } from '../Utils/utils';
1819
import { getFilteredRegions } from '../Utils/utils';
1920
import { DisplayAlertRegions } from './DisplayAlertRegions';
2021

@@ -65,7 +66,9 @@ export const AlertRegions = React.memo((props: AlertRegionsProps) => {
6566
Boolean(serviceType && regions?.length),
6667
serviceType === null ? undefined : serviceType,
6768
{},
68-
{ ...(RESOURCE_FILTER_MAP[serviceType ?? ''] ?? {}) }
69+
{ ...(RESOURCE_FILTER_MAP[serviceType ?? ''] ?? {}) },
70+
undefined,
71+
getFilterFn(serviceType)
6972
);
7073

7174
const titleRef = React.useRef<HTMLDivElement>(null); // Reference to the component title, used for scrolling to the title when the table's page size or page number changes.

packages/manager/src/features/CloudPulse/Alerts/AlertsResources/AlertsResources.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import EntityIcon from 'src/assets/icons/entityIcons/alertsresources.svg';
77
import { DebouncedSearchTextField } from 'src/components/DebouncedSearchTextField';
88
import { useResourcesQuery } from 'src/queries/cloudpulse/resources';
99

10-
import { filterFirewallResources } from '../../Utils/utils';
1110
import { StyledPlaceholder } from '../AlertsDetail/AlertDetail';
1211
import { MULTILINE_ERROR_SEPARATOR } from '../constants';
1312
import { AlertListNoticeMessages } from '../Utils/AlertListNoticeMessages';
@@ -22,6 +21,7 @@ import {
2221
scrollToElement,
2322
} from '../Utils/AlertResourceUtils';
2423
import { AlertSelectedInfoNotice } from '../Utils/AlertSelectedInfoNotice';
24+
import { getFilterFn } from '../Utils/utils';
2525
import { AlertResourcesFilterRenderer } from './AlertsResourcesFilterRenderer';
2626
import {
2727
databaseTypeClassMap,
@@ -42,7 +42,6 @@ import type {
4242
AlertDefinitionType,
4343
CloudPulseServiceType,
4444
Filter,
45-
Firewall,
4645
Region,
4746
} from '@linode/api-v4';
4847

@@ -192,6 +191,9 @@ export const AlertResources = React.memo((props: AlertResourcesProp) => {
192191
return { ...platformFilter, '+and': [typeFilter, regionFilter] };
193192
}, [alertClass, alertType, serviceType, supportedRegionIds]);
194193

194+
// Get the filter function for the service type and entity type if applicable
195+
const filterFn = getFilterFn(serviceType, entityType);
196+
195197
const {
196198
data: resources,
197199
isError: isResourcesError,
@@ -204,10 +206,7 @@ export const AlertResources = React.memo((props: AlertResourcesProp) => {
204206
{},
205207
xFilterToBeApplied,
206208
serviceType === 'firewall' && entityType ? entityType : undefined,
207-
serviceType === 'firewall' && entityType
208-
? (resources: Firewall[]) =>
209-
filterFirewallResources(resources, entityType)
210-
: undefined
209+
filterFn
211210
);
212211

213212
const regionFilteredResources = React.useMemo(() => {

packages/manager/src/features/CloudPulse/Alerts/Utils/utils.test.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { regionFactory } from '@linode/utilities';
1+
import {
2+
linodeAlertsFactory,
3+
linodeFactory,
4+
regionFactory,
5+
} from '@linode/utilities';
26
import { act, renderHook } from '@testing-library/react';
37

48
import { alertFactory, notificationChannelFactory, serviceTypesFactory } from 'src/factories';
@@ -13,6 +17,7 @@ import {
1317
convertSecondsToMinutes,
1418
convertSecondsToOptions,
1519
filterAlerts,
20+
filterLinodeResources,
1621
filterRegionByServiceType,
1722
getSchemaWithEntityIdValidation,
1823
getServiceTypeLabel,
@@ -547,3 +552,18 @@ describe('shouldUseContentsForEmail', () => {
547552
expect(shouldUseContentsForEmail(notificationChannel)).toBe(true);
548553
});
549554
});
555+
556+
describe('filterLinodeResources', () => {
557+
it('should return the filtered linode resources', () => {
558+
const linodes = [
559+
linodeFactory.build({
560+
alerts: {
561+
system_alerts: [1, 2, 3, 4, 5],
562+
user_alerts: [6, 7, 8, 9, 10],
563+
},
564+
}),
565+
linodeFactory.build({ alerts: linodeAlertsFactory.build() }),
566+
];
567+
expect(filterLinodeResources(linodes)).toEqual([linodes[0]]);
568+
});
569+
});

packages/manager/src/features/CloudPulse/Alerts/Utils/utils.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ import {
1313
import type { FieldPath, FieldValues, UseFormSetError } from 'react-hook-form';
1414
import { array, object, string } from 'yup';
1515

16+
import { filterFirewallResources } from '../../Utils/utils';
1617
import { aggregationTypeMap, metricOperatorTypeMap } from '../constants';
1718

1819
import type { CloudPulseResources } from '../../shared/CloudPulseResourcesSelect';
20+
import type { AssociatedEntityType } from '../../shared/types';
1921
import type { AlertRegion } from '../AlertRegions/DisplayAlertRegions';
2022
import type { AlertDimensionsProp } from '../AlertsDetail/DisplayAlertDetailChips';
2123
import type { CreateAlertDefinitionForm } from '../CreateAlert/types';
22-
import type { MonitoringCapabilities } from '@linode/api-v4';
24+
import type { Firewall, Linode, MonitoringCapabilities } from '@linode/api-v4';
2325
import type { Theme } from '@mui/material';
2426
import type {
2527
AclpAlertServiceTypeConfig,
@@ -622,3 +624,37 @@ export const alertsFromEnabledServices = (
622624
(alert) => aclpServices?.[alert.service_type]?.alerts?.enabled ?? false
623625
);
624626
};
627+
628+
/**
629+
* @param serviceType The service type
630+
* @param entityType The entity type
631+
* @returns The filter function for the service type and entity type if applicable
632+
*/
633+
export const getFilterFn = (
634+
serviceType?: CloudPulseServiceType | null,
635+
entityType?: AssociatedEntityType
636+
) => {
637+
if (!serviceType) {
638+
return undefined;
639+
}
640+
if (serviceType === 'firewall' && entityType) {
641+
return (resources: Firewall[]) =>
642+
filterFirewallResources(resources, entityType);
643+
}
644+
if (serviceType === 'linode') {
645+
return (resources: Linode[]) => filterLinodeResources(resources);
646+
}
647+
return undefined;
648+
};
649+
650+
/**
651+
* @param linodes The list of linodes
652+
* @returns The filtered list of linodes that have ACLP alerts
653+
*/
654+
export const filterLinodeResources = (linodes: Linode[]): Linode[] => {
655+
return linodes.filter(
656+
(linode) =>
657+
(linode.alerts.system_alerts?.length ?? 0) > 0 ||
658+
(linode.alerts.user_alerts?.length ?? 0) > 0
659+
);
660+
};

packages/manager/src/mocks/serverHandlers.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,13 @@ export const handlers = [
897897
const linodesWithFirewalls = linodeFactory.buildList(10, {
898898
region: 'ap-west',
899899
});
900+
const linodesWithAclpAlerts = linodeFactory.buildList(10, {
901+
region: 'ap-west',
902+
alerts: {
903+
system_alerts: [1, 2, 3, 4, 5],
904+
user_alerts: [6, 7, 8, 9, 10],
905+
},
906+
});
900907
const metadataLinodeWithCompatibleImage = linodeFactory.build({
901908
image: 'metadata-test-image',
902909
label: 'metadata-test-image',
@@ -984,6 +991,7 @@ export const handlers = [
984991
});
985992
const linodes = [
986993
...linodesWithFirewalls,
994+
...linodesWithAclpAlerts,
987995
...mtcLinodes,
988996
...aclpSupportedRegionLinodes,
989997
nonMTCPlanInMTCSupportedRegionsLinode,

packages/utilities/src/__data__/regionsData.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const regions: Region[] = [
2929
site_type: 'core',
3030
status: 'ok',
3131
monitors: {
32-
alerts: ['Cloud Firewall', 'Object Storage', 'Block Storage'],
32+
alerts: ['Linodes', 'Cloud Firewall', 'Object Storage', 'Block Storage'],
3333
metrics: [
3434
'Object Storage',
3535
'Cloud Firewall',

0 commit comments

Comments
 (0)