diff --git a/api/src/backend/api/fixtures/dev/2_dev_providers.json b/api/src/backend/api/fixtures/dev/2_dev_providers.json
index a4d73950cc..72e0602055 100644
--- a/api/src/backend/api/fixtures/dev/2_dev_providers.json
+++ b/api/src/backend/api/fixtures/dev/2_dev_providers.json
@@ -122,6 +122,22 @@
"scanner_args": {}
}
},
+ {
+ "model": "api.provider",
+ "pk": "7791914f-d646-4fe2-b2ed-73f2c6499a36",
+ "fields": {
+ "tenant": "12646005-9067-4d2a-a098-8bb378604362",
+ "inserted_at": "2024-10-18T10:45:26.352Z",
+ "updated_at": "2024-10-18T11:16:23.533Z",
+ "provider": "kubernetes",
+ "uid": "gke_lucky-coast-419309_us-central1_autopilot-cluster-2",
+ "alias": "k8s_testing_2",
+ "connected": true,
+ "connection_last_checked_at": "2024-10-18T11:16:23.503Z",
+ "metadata": {},
+ "scanner_args": {}
+ }
+ },
{
"model": "api.providersecret",
"pk": "11491b47-75ae-4f71-ad8d-3e630a72182e",
diff --git a/api/src/backend/api/fixtures/dev/3_dev_scans.json b/api/src/backend/api/fixtures/dev/3_dev_scans.json
index d03f4ac07b..4f6d284b99 100644
--- a/api/src/backend/api/fixtures/dev/3_dev_scans.json
+++ b/api/src/backend/api/fixtures/dev/3_dev_scans.json
@@ -11,9 +11,7 @@
"unique_resource_count": 1,
"duration": 5,
"scanner_args": {
- "checks_to_execute": [
- "accessanalyzer_enabled"
- ]
+ "checks_to_execute": ["accessanalyzer_enabled"]
},
"inserted_at": "2024-09-01T17:25:27.050Z",
"started_at": "2024-09-01T17:25:27.050Z",
@@ -33,9 +31,7 @@
"unique_resource_count": 1,
"duration": 20,
"scanner_args": {
- "checks_to_execute": [
- "accessanalyzer_enabled"
- ]
+ "checks_to_execute": ["accessanalyzer_enabled"]
},
"inserted_at": "2024-09-02T17:24:27.050Z",
"started_at": "2024-09-02T17:24:27.050Z",
@@ -55,9 +51,7 @@
"unique_resource_count": 10,
"duration": 10,
"scanner_args": {
- "checks_to_execute": [
- "cloudsql_instance_automated_backups"
- ]
+ "checks_to_execute": ["cloudsql_instance_automated_backups"]
},
"inserted_at": "2024-09-02T19:26:27.050Z",
"started_at": "2024-09-02T19:26:27.050Z",
@@ -77,9 +71,7 @@
"unique_resource_count": 1,
"duration": 35,
"scanner_args": {
- "checks_to_execute": [
- "accessanalyzer_enabled"
- ]
+ "checks_to_execute": ["accessanalyzer_enabled"]
},
"inserted_at": "2024-09-02T19:27:27.050Z",
"started_at": "2024-09-02T19:27:27.050Z",
@@ -97,9 +89,7 @@
"name": "test scheduled aws scan",
"state": "available",
"scanner_args": {
- "checks_to_execute": [
- "cloudformation_stack_outputs_find_secrets"
- ]
+ "checks_to_execute": ["cloudformation_stack_outputs_find_secrets"]
},
"scheduled_at": "2030-09-02T19:20:27.050Z",
"inserted_at": "2024-09-02T19:24:27.050Z",
@@ -178,9 +168,7 @@
"unique_resource_count": 19,
"progress": 100,
"scanner_args": {
- "checks_to_execute": [
- "accessanalyzer_enabled"
- ]
+ "checks_to_execute": ["accessanalyzer_enabled"]
},
"duration": 7,
"scheduled_at": null,
@@ -190,6 +178,56 @@
"completed_at": "2024-10-18T10:46:05.127Z"
}
},
+ {
+ "model": "api.scan",
+ "pk": "6dd8925f-a52d-48de-a546-d2d90db30ab1",
+ "fields": {
+ "tenant": "12646005-9067-4d2a-a098-8bb378604362",
+ "name": "real scan azure",
+ "provider": "1b59e032-3eb6-4694-93a5-df84cd9b3ce2",
+ "trigger": "manual",
+ "state": "completed",
+ "unique_resource_count": 20,
+ "progress": 100,
+ "scanner_args": {
+ "checks_to_execute": [
+ "accessanalyzer_enabled",
+ "account_security_contact_information_is_registered"
+ ]
+ },
+ "duration": 4,
+ "scheduled_at": null,
+ "inserted_at": "2024-10-18T11:16:21.358Z",
+ "updated_at": "2024-10-18T11:16:26.060Z",
+ "started_at": "2024-10-18T11:16:21.593Z",
+ "completed_at": "2024-10-18T11:16:26.060Z"
+ }
+ },
+ {
+ "model": "api.scan",
+ "pk": "4ca7ce89-3236-41a8-a369-8937bc152af5",
+ "fields": {
+ "tenant": "12646005-9067-4d2a-a098-8bb378604362",
+ "name": "real scan k8s",
+ "provider": "7791914f-d646-4fe2-b2ed-73f2c6499a36",
+ "trigger": "manual",
+ "state": "completed",
+ "unique_resource_count": 20,
+ "progress": 100,
+ "scanner_args": {
+ "checks_to_execute": [
+ "accessanalyzer_enabled",
+ "account_security_contact_information_is_registered"
+ ]
+ },
+ "duration": 4,
+ "scheduled_at": null,
+ "inserted_at": "2024-10-18T11:16:21.358Z",
+ "updated_at": "2024-10-18T11:16:26.060Z",
+ "started_at": "2024-10-18T11:16:21.593Z",
+ "completed_at": "2024-10-18T11:16:26.060Z"
+ }
+ },
{
"model": "api.scan",
"pk": "01929f57-c0ee-7553-be0b-cbde006fb6f7",
diff --git a/ui/actions/compliances/compliances.ts b/ui/actions/compliances/compliances.ts
index e9c8814c31..5eb94cde98 100644
--- a/ui/actions/compliances/compliances.ts
+++ b/ui/actions/compliances/compliances.ts
@@ -7,9 +7,11 @@ import { parseStringify } from "@/lib";
export const getCompliancesOverview = async ({
scanId,
region,
+ query,
}: {
scanId: string;
region?: string | string[];
+ query?: string;
}) => {
const session = await auth();
@@ -17,6 +19,7 @@ export const getCompliancesOverview = async ({
const url = new URL(`${keyServer}/compliance-overviews`);
if (scanId) url.searchParams.append("filter[scan_id]", scanId);
+ if (query) url.searchParams.append("filter[search]", query);
if (region) {
const regionValue = Array.isArray(region) ? region.join(",") : region;
diff --git a/ui/actions/findings/findings.ts b/ui/actions/findings/findings.ts
index 859dc86b7e..901228a91a 100644
--- a/ui/actions/findings/findings.ts
+++ b/ui/actions/findings/findings.ts
@@ -82,17 +82,15 @@ export const getMetadataInfo = async ({
});
if (!response.ok) {
- throw new Error(
- `Failed to fetch services regions: ${response.statusText}`,
- );
+ throw new Error(`Failed to fetch metadata info: ${response.statusText}`);
}
- const data = await response.json();
- const parsedData = parseStringify(data);
+ const parsedData = parseStringify(await response.json());
+
return parsedData;
} catch (error) {
// eslint-disable-next-line no-console
- console.error("Error fetching services regions:", error);
+ console.error("Error fetching metadata info:", error);
return undefined;
}
};
diff --git a/ui/app/(prowler)/compliance/page.tsx b/ui/app/(prowler)/compliance/page.tsx
index 22164bbcc3..68789e6900 100644
--- a/ui/app/(prowler)/compliance/page.tsx
+++ b/ui/app/(prowler)/compliance/page.tsx
@@ -4,88 +4,107 @@ import { Spacer } from "@nextui-org/react";
import { Suspense } from "react";
import { getCompliancesOverview } from "@/actions/compliances";
+import { getMetadataInfo } from "@/actions/findings";
+import { getProvider } from "@/actions/providers";
import { getScans } from "@/actions/scans";
import {
ComplianceCard,
ComplianceSkeletonGrid,
+ NoScansAvailable,
} from "@/components/compliance";
import { DataCompliance } from "@/components/compliance/data-compliance";
+import { FilterControls } from "@/components/filters";
import { ContentLayout } from "@/components/ui";
-import { ComplianceOverviewData, SearchParamsProps } from "@/types";
+import { DataTableFilterCustom } from "@/components/ui/table/data-table-filter-custom";
+import { ComplianceOverviewData, ScanProps, SearchParamsProps } from "@/types";
export default async function Compliance({
searchParams,
}: {
searchParams: SearchParamsProps;
}) {
- let scansData;
- let scanList: {
- id: string;
- name: string;
- state: string;
- progress: number;
- }[] = [];
+ const searchParamsKey = JSON.stringify(searchParams || {});
- try {
- scansData = await getScans({});
- scanList =
- scansData?.data
- ?.filter(
- (scan: any) =>
- scan.attributes.state === "completed" &&
- scan.attributes.progress === 100,
- )
- .map((scan: any) => ({
- id: scan.id,
- name: scan.attributes.name || "Unnamed Scan",
- state: scan.attributes.state,
- progress: scan.attributes.progress,
- })) || [];
- } catch (error) {
- // eslint-disable-next-line no-console
- console.error("Error fetching scans data:", error);
+ const filters = Object.fromEntries(
+ Object.entries(searchParams).filter(([key]) => key.startsWith("filter[")),
+ );
+
+ const scansData = await getScans({
+ filters: {
+ "filter[state]": "completed",
+ },
+ });
+
+ if (!scansData?.data) {
+ return
+ {scan.attributes.name || "- -"} +
++ A scan must be completed before generating a compliance + report. +
+diff --git a/ui/types/components.ts b/ui/types/components.ts index 312cb51a18..342e4d401f 100644 --- a/ui/types/components.ts +++ b/ui/types/components.ts @@ -42,6 +42,18 @@ export interface CollapseMenuButtonProps { isOpen: boolean | undefined; } +export interface SelectScanComplianceDataProps { + scans: (ScanProps & { + providerInfo: { + provider: "aws" | "azure" | "gcp" | "kubernetes"; + uid: string; + alias: string; + }; + })[]; + selectedScanId: string; + onSelectionChange: (selectedKey: string) => void; +} + export type NextUIVariants = | "solid" | "faded"