diff --git a/deepfence_frontend/apps/dashboard/src/features/malwares/pages/MostExploitableMalwares.tsx b/deepfence_frontend/apps/dashboard/src/features/malwares/pages/MostExploitableMalwares.tsx index 5775165a3f..02654dc922 100644 --- a/deepfence_frontend/apps/dashboard/src/features/malwares/pages/MostExploitableMalwares.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/malwares/pages/MostExploitableMalwares.tsx @@ -36,6 +36,10 @@ const DEFAULT_PAGE_SIZE = 10; const FILTER_SEARCHPARAMS: Record = { severity: 'Severity', + hosts: 'Host', + containers: 'Container', + containerImages: 'Container Images', + clusters: 'Clusters', }; const getAppliedFiltersCount = (searchParams: URLSearchParams) => { return Object.keys(FILTER_SEARCHPARAMS).reduce((prev, curr) => { diff --git a/deepfence_frontend/apps/dashboard/src/features/malwares/pages/UniqueMalwares.tsx b/deepfence_frontend/apps/dashboard/src/features/malwares/pages/UniqueMalwares.tsx index 5ed49dcc9b..46d62f69d2 100644 --- a/deepfence_frontend/apps/dashboard/src/features/malwares/pages/UniqueMalwares.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/malwares/pages/UniqueMalwares.tsx @@ -37,6 +37,10 @@ const DEFAULT_PAGE_SIZE = 10; const FILTER_SEARCHPARAMS: Record = { severity: 'Severity', + hosts: 'Host', + containers: 'Container', + containerImages: 'Container Images', + clusters: 'Clusters', }; const getAppliedFiltersCount = (searchParams: URLSearchParams) => { return Object.keys(FILTER_SEARCHPARAMS).reduce((prev, curr) => { diff --git a/deepfence_frontend/apps/dashboard/src/features/secrets/pages/MostExploitableSecrets.tsx b/deepfence_frontend/apps/dashboard/src/features/secrets/pages/MostExploitableSecrets.tsx index 2343421353..bd1af50eed 100644 --- a/deepfence_frontend/apps/dashboard/src/features/secrets/pages/MostExploitableSecrets.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/secrets/pages/MostExploitableSecrets.tsx @@ -35,6 +35,10 @@ const DEFAULT_PAGE_SIZE = 10; const FILTER_SEARCHPARAMS: Record = { severity: 'Severity', + hosts: 'Host', + containers: 'Container', + containerImages: 'Container Images', + clusters: 'Clusters', }; const getAppliedFiltersCount = (searchParams: URLSearchParams) => { return Object.keys(FILTER_SEARCHPARAMS).reduce((prev, curr) => { diff --git a/deepfence_frontend/apps/dashboard/src/features/secrets/pages/UniqueSecrets.tsx b/deepfence_frontend/apps/dashboard/src/features/secrets/pages/UniqueSecrets.tsx index bb0a691163..ba03c41c64 100644 --- a/deepfence_frontend/apps/dashboard/src/features/secrets/pages/UniqueSecrets.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/secrets/pages/UniqueSecrets.tsx @@ -37,6 +37,10 @@ const DEFAULT_PAGE_SIZE = 10; const FILTER_SEARCHPARAMS: Record = { severity: 'Severity', + hosts: 'Host', + containers: 'Container', + containerImages: 'Container Images', + clusters: 'Clusters', }; const getAppliedFiltersCount = (searchParams: URLSearchParams) => { return Object.keys(FILTER_SEARCHPARAMS).reduce((prev, curr) => { diff --git a/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/ContainersTable.tsx b/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/ContainersTable.tsx index 5ba89e4e11..c4f2042794 100644 --- a/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/ContainersTable.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/ContainersTable.tsx @@ -24,6 +24,7 @@ import { } from '@/components/ConfigureScanModal'; import { DFLink } from '@/components/DFLink'; import { FilterBadge } from '@/components/filters/FilterBadge'; +import { SearchableClusterList } from '@/components/forms/SearchableClusterList'; import { SearchableHostList } from '@/components/forms/SearchableHostList'; import { CaretDown } from '@/components/icons/common/CaretDown'; import { FilterIcon } from '@/components/icons/common/Filter'; @@ -204,6 +205,7 @@ const FILTER_SEARCHPARAMS: Record = { secretScanStatus: 'Secret scan status', malwareScanStatus: 'Malware scan status', hosts: 'Host', + clusters: 'Cluster', }; const getAppliedFiltersCount = (searchParams: URLSearchParams) => { @@ -347,6 +349,26 @@ function Filters() { }); }} /> + { + setSearchParams((prev) => { + prev.delete('clusters'); + prev.delete('page'); + return prev; + }); + }} + onChange={(value) => { + setSearchParams((prev) => { + prev.delete('clusters'); + value.forEach((cluster) => { + prev.append('clusters', cluster); + }); + prev.delete('page'); + return prev; + }); + }} + /> {appliedFilterCount > 0 ? (
@@ -413,6 +435,7 @@ function useSearchContainersWithPagination() { | MalwareScanGroupedStatus | undefined, order: getOrderFromSearchParams(searchParams), + clusterIds: searchParams.getAll('clusters'), }), keepPreviousData: true, }); diff --git a/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/HostsTable.tsx b/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/HostsTable.tsx index 8d64b3397e..8c4b335693 100644 --- a/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/HostsTable.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/HostsTable.tsx @@ -232,6 +232,7 @@ const FILTER_SEARCHPARAMS: Record = { complianceScanStatus: 'Posture scan status', cloudProvider: 'Cloud provider', agentRunning: 'Agent running', + clusters: 'Cluster', }; const getAppliedFiltersCount = (searchParams: URLSearchParams) => { diff --git a/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/KubernetesTable.tsx b/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/KubernetesTable.tsx index 2d8668a699..2386ff3b65 100644 --- a/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/KubernetesTable.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/KubernetesTable.tsx @@ -22,8 +22,10 @@ import { ConfigureScanModal, ConfigureScanModalProps, } from '@/components/ConfigureScanModal'; +import { DFLink } from '@/components/DFLink'; import { FilterBadge } from '@/components/filters/FilterBadge'; import { CaretDown } from '@/components/icons/common/CaretDown'; +import { EllipsisIcon } from '@/components/icons/common/Ellipsis'; import { FilterIcon } from '@/components/icons/common/Filter'; import { TimesIcon } from '@/components/icons/common/Times'; import { MalwareIcon } from '@/components/sideNavigation/icons/Malware'; @@ -370,7 +372,44 @@ const DataTable = ({ } else { name = info.row.original.node_id; } - return ; + return ( +
+ + + + Go to hosts + + + + + Go to containers + + + + + Go to pods + + + + } + > +
+ +
+
+ +
+ ); }, header: () => 'Name', minSize: 150, diff --git a/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/PodsTable.tsx b/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/PodsTable.tsx index 89e3e75c14..6ee80994c1 100644 --- a/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/PodsTable.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/PodsTable.tsx @@ -285,7 +285,7 @@ function useSearchPodsWithPagination() { pageSize: parseInt(searchParams.get('size') ?? String(DEFAULT_PAGE_SIZE)), order: getOrderFromSearchParams(searchParams), hosts: searchParams.getAll('hosts'), - clusters: searchParams.getAll('clusters'), + clusterNames: searchParams.getAll('clusters'), pods: searchParams.getAll('pods'), kubernetesStatus: searchParams.get('kubernetesStatus') ?? undefined, }), diff --git a/deepfence_frontend/apps/dashboard/src/features/vulnerabilities/pages/MostExploitableVulnerabilities.tsx b/deepfence_frontend/apps/dashboard/src/features/vulnerabilities/pages/MostExploitableVulnerabilities.tsx index 041247865d..0f82d08ae5 100644 --- a/deepfence_frontend/apps/dashboard/src/features/vulnerabilities/pages/MostExploitableVulnerabilities.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/vulnerabilities/pages/MostExploitableVulnerabilities.tsx @@ -37,6 +37,10 @@ const DEFAULT_PAGE_SIZE = 10; const FILTER_SEARCHPARAMS: Record = { liveConnection: 'Live Connection', severity: 'CVE Severity', + hosts: 'Host', + containers: 'Container', + containerImages: 'Container Images', + clusters: 'Clusters', }; const getAppliedFiltersCount = (searchParams: URLSearchParams) => { return Object.keys(FILTER_SEARCHPARAMS).reduce((prev, curr) => { diff --git a/deepfence_frontend/apps/dashboard/src/features/vulnerabilities/pages/UniqueVulnerabilities.tsx b/deepfence_frontend/apps/dashboard/src/features/vulnerabilities/pages/UniqueVulnerabilities.tsx index e5f1d33cc3..4fed12b82e 100644 --- a/deepfence_frontend/apps/dashboard/src/features/vulnerabilities/pages/UniqueVulnerabilities.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/vulnerabilities/pages/UniqueVulnerabilities.tsx @@ -39,6 +39,10 @@ const DEFAULT_PAGE_SIZE = 10; const FILTER_SEARCHPARAMS: Record = { liveConnection: 'Live Connection', severity: 'CVE Severity', + hosts: 'Host', + containers: 'Container', + containerImages: 'Container Images', + clusters: 'Clusters', }; const getAppliedFiltersCount = (searchParams: URLSearchParams) => { return Object.keys(FILTER_SEARCHPARAMS).reduce((prev, curr) => { diff --git a/deepfence_frontend/apps/dashboard/src/queries/search.tsx b/deepfence_frontend/apps/dashboard/src/queries/search.tsx index 3efb066c83..b3631a6602 100644 --- a/deepfence_frontend/apps/dashboard/src/queries/search.tsx +++ b/deepfence_frontend/apps/dashboard/src/queries/search.tsx @@ -895,6 +895,7 @@ export const searchQueries = createQueryKeys('search', { sortBy: string; descending: boolean; }; + clusterIds: string[]; }) => { return { queryKey: [filters], @@ -907,6 +908,7 @@ export const searchQueries = createQueryKeys('search', { secretScanStatus, malwareScanStatus, order, + clusterIds, } = filters; const searchSearchNodeReq: SearchSearchNodeReq = { node_filter: { @@ -991,7 +993,12 @@ export const searchQueries = createQueryKeys('search', { }; } } - + if (clusterIds?.length) { + searchSearchNodeReq.node_filter.filters.contains_filter.filter_in = { + ...searchSearchNodeReq.node_filter.filters.contains_filter.filter_in, + kubernetes_cluster_id: clusterIds, + }; + } if (order) { searchSearchNodeReq.node_filter.filters.order_filter.order_fields?.push({ field_name: order.sortBy, @@ -1044,7 +1051,7 @@ export const searchQueries = createQueryKeys('search', { page: number; pageSize: number; hosts: string[]; - clusters: string[]; + clusterNames: string[]; pods: string[]; kubernetesStatus?: string; order?: { @@ -1055,7 +1062,7 @@ export const searchQueries = createQueryKeys('search', { return { queryKey: [filters], queryFn: async () => { - const { page, pageSize, hosts, pods, order, clusters, kubernetesStatus } = + const { page, pageSize, hosts, pods, order, clusterNames, kubernetesStatus } = filters; const searchSearchNodeReq: SearchSearchNodeReq = { node_filter: { @@ -1065,7 +1072,9 @@ export const searchQueries = createQueryKeys('search', { filter_in: { active: [true], ...(hosts.length ? { host_name: hosts } : {}), - ...(clusters.length ? { kubernetes_cluster_name: clusters } : {}), + ...(clusterNames.length + ? { kubernetes_cluster_name: clusterNames } + : {}), ...(pods.length ? { pod_name: pods } : {}), }, },