From 76837fb3fd14fde62b938129e57e9b43037ad4a0 Mon Sep 17 00:00:00 2001 From: milan-deepfence Date: Wed, 19 Jun 2024 15:56:21 +0530 Subject: [PATCH 1/5] add azure subscription and azure tenants --- .../apps/dashboard/api-spec.json | 220 +++++++++++++-- .../api/generated/.openapi-generator/FILES | 6 +- .../src/api/generated/apis/ComplianceApi.ts | 124 +++++++++ .../src/api/generated/apis/SettingsApi.ts | 28 +- .../generated/models/ModelCloudCompliance.ts | 3 +- .../models/ModelCloudNodeAccountsListReq.ts | 3 +- .../models/ModelCloudNodeComplianceControl.ts | 24 ++ .../models/ModelCloudNodeControlReq.ts | 3 +- .../ModelComplinaceScanResultsGroupReq.ts | 82 ++++++ .../ModelComplinaceScanResultsGroupResp.ts | 65 +++++ ...uest.ts => SettingSettingUpdateRequest.ts} | 26 +- ...Response.ts => SettingSettingsResponse.ts} | 26 +- .../src/api/generated/models/index.ts | 6 +- .../forms/SearchableCloudAccountsList.tsx | 14 +- .../src/components/icons/posture/index.tsx | 17 +- .../ComplianceScanConfigureForm.tsx | 37 +-- .../components/report-form/AdvanceFilter.tsx | 10 +- .../features/postures/pages/AccountAdd.tsx | 2 +- .../src/features/postures/pages/Accounts.tsx | 258 +++++++++++------- .../src/features/postures/pages/Posture.tsx | 68 ++--- .../pages/PostureCloudDetailModal.tsx | 66 +++-- .../pages/PostureCloudScanResults.tsx | 10 +- .../postures/pages/PostureScanResults.tsx | 10 +- .../src/features/postures/utils/index.ts | 133 +++++++++ .../apps/dashboard/src/queries/onboard.ts | 40 ++- .../apps/dashboard/src/types/common.ts | 44 +-- 26 files changed, 1004 insertions(+), 321 deletions(-) create mode 100644 deepfence_frontend/apps/dashboard/src/api/generated/models/ModelComplinaceScanResultsGroupReq.ts create mode 100644 deepfence_frontend/apps/dashboard/src/api/generated/models/ModelComplinaceScanResultsGroupResp.ts rename deepfence_frontend/apps/dashboard/src/api/generated/models/{ModelSettingUpdateRequest.ts => SettingSettingUpdateRequest.ts} (64%) rename deepfence_frontend/apps/dashboard/src/api/generated/models/{ModelSettingsResponse.ts => SettingSettingsResponse.ts} (72%) create mode 100644 deepfence_frontend/apps/dashboard/src/features/postures/utils/index.ts diff --git a/deepfence_frontend/apps/dashboard/api-spec.json b/deepfence_frontend/apps/dashboard/api-spec.json index de2f215fe4..3648a16280 100644 --- a/deepfence_frontend/apps/dashboard/api-spec.json +++ b/deepfence_frontend/apps/dashboard/api-spec.json @@ -6864,6 +6864,118 @@ "security": [{ "bearer_token": [] }] } }, + "/deepfence/scan/results/count/group/cloud-compliance": { + "post": { + "tags": ["Compliance"], + "summary": "Count Cloud Compliance Results by Control ID", + "description": "Count Cloud Compliance Results grouped by Control ID", + "operationId": "groupResultsCloudCompliance", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModelComplinaceScanResultsGroupReq" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModelComplinaceScanResultsGroupResp" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsBadRequestResponse" } + } + } + }, + "401": { "description": "Unauthorized" }, + "403": { "description": "Forbidden" }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsFailureResponse" } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsFailureResponse" } + } + } + } + }, + "security": [{ "bearer_token": [] }] + } + }, + "/deepfence/scan/results/count/group/compliance": { + "post": { + "tags": ["Compliance"], + "summary": "Count Compliance Results by Control ID", + "description": "Count Compliance Results grouped by Control ID", + "operationId": "groupResultsCompliance", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModelComplinaceScanResultsGroupReq" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModelComplinaceScanResultsGroupResp" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsBadRequestResponse" } + } + } + }, + "401": { "description": "Unauthorized" }, + "403": { "description": "Forbidden" }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsFailureResponse" } + } + } + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ApiDocsFailureResponse" } + } + } + } + }, + "security": [{ "bearer_token": [] }] + } + }, "/deepfence/scan/results/count/group/malware": { "get": { "tags": ["Malware Scan"], @@ -11376,7 +11488,7 @@ "application/json": { "schema": { "type": "array", - "items": { "$ref": "#/components/schemas/ModelSettingsResponse" } + "items": { "$ref": "#/components/schemas/SettingSettingsResponse" } } } } @@ -11428,7 +11540,7 @@ "requestBody": { "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ModelSettingUpdateRequest" } + "schema": { "$ref": "#/components/schemas/SettingSettingUpdateRequest" } } } }, @@ -13335,7 +13447,16 @@ "account_id": { "type": "string" }, "cloud_provider": { "type": "string" }, "compliance_check_type": { - "enum": ["hipaa", "gdpr", "pci", "nist", "cis", "soc_2", "nsa-cisa"], + "enum": [ + "hipaa", + "gdpr", + "pci", + "nist", + "cis", + "soc_2", + "nsa-cisa", + "aws_foundational_security" + ], "type": "string" }, "control_id": { "type": "string" }, @@ -13461,7 +13582,16 @@ "type": "object", "properties": { "cloud_provider": { - "enum": ["aws", "gcp", "azure", "linux", "kubernetes", "aws_org", "gcp_org"], + "enum": [ + "aws", + "gcp", + "azure", + "linux", + "kubernetes", + "aws_org", + "gcp_org", + "azure_org" + ], "type": "string" }, "window": { "$ref": "#/components/schemas/ModelFetchWindow" } @@ -13487,9 +13617,12 @@ "items": { "type": "string" }, "nullable": true }, + "category_hierarchy_short": { "type": "string" }, + "compliance_type": { "type": "string" }, "control_id": { "type": "string" }, "description": { "type": "string" }, "enabled": { "type": "boolean" }, + "node_id": { "type": "string" }, "service": { "type": "string" }, "title": { "type": "string" } } @@ -13503,7 +13636,16 @@ "type": "string" }, "compliance_type": { - "enum": ["hipaa", "gdpr", "pci", "nist", "cis", "soc_2", "nsa-cisa"], + "enum": [ + "hipaa", + "gdpr", + "pci", + "nist", + "cis", + "soc_2", + "nsa-cisa", + "aws_foundational_security" + ], "type": "string" }, "node_id": { "type": "string" } @@ -13768,6 +13910,27 @@ } } }, + "ModelComplinaceScanResultsGroupReq": { + "required": ["scan_id", "fields_filter"], + "type": "object", + "properties": { + "fields_filter": { "$ref": "#/components/schemas/ReportersFieldsFilters" }, + "scan_id": { "type": "string" } + } + }, + "ModelComplinaceScanResultsGroupResp": { + "type": "object", + "properties": { + "groups": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": { "type": "integer" } + }, + "nullable": true + } + } + }, "ModelConnection": { "type": "object", "properties": { @@ -15332,28 +15495,6 @@ } } }, - "ModelSettingUpdateRequest": { - "required": ["key", "value"], - "type": "object", - "properties": { - "key": { - "enum": ["console_url", "file_server_url", "inactive_delete_scan_results"], - "type": "string" - }, - "value": { "type": "string" } - } - }, - "ModelSettingsResponse": { - "required": ["id", "key", "label", "value", "description"], - "type": "object", - "properties": { - "description": { "type": "string" }, - "id": { "type": "integer" }, - "key": { "type": "string" }, - "label": { "type": "string" }, - "value": {} - } - }, "ModelStopScanRequest": { "required": ["scan_ids", "scan_type"], "type": "object", @@ -15973,6 +16114,28 @@ "window": { "$ref": "#/components/schemas/ModelFetchWindow" } } }, + "SettingSettingUpdateRequest": { + "required": ["key", "value"], + "type": "object", + "properties": { + "key": { + "enum": ["console_url", "file_server_url", "inactive_delete_scan_results"], + "type": "string" + }, + "value": { "type": "string" } + } + }, + "SettingSettingsResponse": { + "required": ["id", "key", "label", "value", "description"], + "type": "object", + "properties": { + "description": { "type": "string" }, + "id": { "type": "integer" }, + "key": { "type": "string" }, + "label": { "type": "string" }, + "value": {} + } + }, "SqlNullTime": { "type": "object" }, "UtilsAdvancedReportFilters": { "type": "object", @@ -16031,7 +16194,8 @@ "nist", "hipaa", "pci", - "soc_2" + "soc_2", + "aws_foundational_security" ], "type": "array", "items": { "type": "string" }, diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/.openapi-generator/FILES b/deepfence_frontend/apps/dashboard/src/api/generated/.openapi-generator/FILES index fbbded2501..70c6190c0d 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/.openapi-generator/FILES +++ b/deepfence_frontend/apps/dashboard/src/api/generated/.openapi-generator/FILES @@ -102,6 +102,8 @@ models/ModelComplianceScanInfo.ts models/ModelComplianceScanResult.ts models/ModelComplianceScanStatusResp.ts models/ModelComplianceScanTriggerReq.ts +models/ModelComplinaceScanResultsGroupReq.ts +models/ModelComplinaceScanResultsGroupResp.ts models/ModelConnection.ts models/ModelContainer.ts models/ModelContainerImage.ts @@ -195,8 +197,6 @@ models/ModelSecretRule.ts models/ModelSecretScanResult.ts models/ModelSecretScanResultRules.ts models/ModelSecretScanTriggerReq.ts -models/ModelSettingUpdateRequest.ts -models/ModelSettingsResponse.ts models/ModelStopScanRequest.ts models/ModelSummary.ts models/ModelTopologyDeltaReq.ts @@ -230,6 +230,8 @@ models/SearchSearchCountResp.ts models/SearchSearchFilter.ts models/SearchSearchNodeReq.ts models/SearchSearchScanReq.ts +models/SettingSettingUpdateRequest.ts +models/SettingSettingsResponse.ts models/UtilsAdvancedReportFilters.ts models/UtilsReportFilters.ts models/UtilsReportOptions.ts diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/apis/ComplianceApi.ts b/deepfence_frontend/apps/dashboard/src/api/generated/apis/ComplianceApi.ts index 1d01a813fa..e0d1cf5569 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/apis/ComplianceApi.ts +++ b/deepfence_frontend/apps/dashboard/src/api/generated/apis/ComplianceApi.ts @@ -21,6 +21,8 @@ import type { IngestersComplianceScanStatus, ModelComplianceScanResult, ModelComplianceScanTriggerReq, + ModelComplinaceScanResultsGroupReq, + ModelComplinaceScanResultsGroupResp, ModelScanListReq, ModelScanListResp, ModelScanResultsReq, @@ -43,6 +45,10 @@ import { ModelComplianceScanResultToJSON, ModelComplianceScanTriggerReqFromJSON, ModelComplianceScanTriggerReqToJSON, + ModelComplinaceScanResultsGroupReqFromJSON, + ModelComplinaceScanResultsGroupReqToJSON, + ModelComplinaceScanResultsGroupRespFromJSON, + ModelComplinaceScanResultsGroupRespToJSON, ModelScanListReqFromJSON, ModelScanListReqToJSON, ModelScanListRespFromJSON, @@ -65,6 +71,14 @@ export interface CountResultsComplianceScanRequest { modelScanResultsReq?: ModelScanResultsReq; } +export interface GroupResultsCloudComplianceRequest { + modelComplinaceScanResultsGroupReq?: ModelComplinaceScanResultsGroupReq; +} + +export interface GroupResultsComplianceRequest { + modelComplinaceScanResultsGroupReq?: ModelComplinaceScanResultsGroupReq; +} + export interface IngestComplianceScanStatusRequest { ingestersComplianceScanStatus?: Array | null; } @@ -116,6 +130,38 @@ export interface ComplianceApiInterface { */ countResultsComplianceScan(requestParameters: CountResultsComplianceScanRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + /** + * Count Cloud Compliance Results grouped by Control ID + * @summary Count Cloud Compliance Results by Control ID + * @param {ModelComplinaceScanResultsGroupReq} [modelComplinaceScanResultsGroupReq] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ComplianceApiInterface + */ + groupResultsCloudComplianceRaw(requestParameters: GroupResultsCloudComplianceRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Count Cloud Compliance Results grouped by Control ID + * Count Cloud Compliance Results by Control ID + */ + groupResultsCloudCompliance(requestParameters: GroupResultsCloudComplianceRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Count Compliance Results grouped by Control ID + * @summary Count Compliance Results by Control ID + * @param {ModelComplinaceScanResultsGroupReq} [modelComplinaceScanResultsGroupReq] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ComplianceApiInterface + */ + groupResultsComplianceRaw(requestParameters: GroupResultsComplianceRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Count Compliance Results grouped by Control ID + * Count Compliance Results by Control ID + */ + groupResultsCompliance(requestParameters: GroupResultsComplianceRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + /** * Ingest compliance issues found while scanning the agent * @summary Ingest Compliance Scan Status @@ -274,6 +320,84 @@ export class ComplianceApi extends runtime.BaseAPI implements ComplianceApiInter return await response.value(); } + /** + * Count Cloud Compliance Results grouped by Control ID + * Count Cloud Compliance Results by Control ID + */ + async groupResultsCloudComplianceRaw(requestParameters: GroupResultsCloudComplianceRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer_token", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/deepfence/scan/results/count/group/cloud-compliance`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: ModelComplinaceScanResultsGroupReqToJSON(requestParameters.modelComplinaceScanResultsGroupReq), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ModelComplinaceScanResultsGroupRespFromJSON(jsonValue)); + } + + /** + * Count Cloud Compliance Results grouped by Control ID + * Count Cloud Compliance Results by Control ID + */ + async groupResultsCloudCompliance(requestParameters: GroupResultsCloudComplianceRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.groupResultsCloudComplianceRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Count Compliance Results grouped by Control ID + * Count Compliance Results by Control ID + */ + async groupResultsComplianceRaw(requestParameters: GroupResultsComplianceRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer_token", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/deepfence/scan/results/count/group/compliance`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: ModelComplinaceScanResultsGroupReqToJSON(requestParameters.modelComplinaceScanResultsGroupReq), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ModelComplinaceScanResultsGroupRespFromJSON(jsonValue)); + } + + /** + * Count Compliance Results grouped by Control ID + * Count Compliance Results by Control ID + */ + async groupResultsCompliance(requestParameters: GroupResultsComplianceRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.groupResultsComplianceRaw(requestParameters, initOverrides); + return await response.value(); + } + /** * Ingest compliance issues found while scanning the agent * Ingest Compliance Scan Status diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/apis/SettingsApi.ts b/deepfence_frontend/apps/dashboard/src/api/generated/apis/SettingsApi.ts index dd08a1d9ae..68679116ab 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/apis/SettingsApi.ts +++ b/deepfence_frontend/apps/dashboard/src/api/generated/apis/SettingsApi.ts @@ -29,12 +29,12 @@ import type { ModelMessageResponse, ModelRegisterLicenseRequest, ModelRegisterLicenseResponse, - ModelSettingUpdateRequest, - ModelSettingsResponse, ModelUpdateScheduledTaskRequest, PostgresqlDbGetAuditLogsRow, PostgresqlDbScheduler, SearchSearchCountResp, + SettingSettingUpdateRequest, + SettingSettingsResponse, } from '../models'; import { ApiDocsBadRequestResponseFromJSON, @@ -65,10 +65,6 @@ import { ModelRegisterLicenseRequestToJSON, ModelRegisterLicenseResponseFromJSON, ModelRegisterLicenseResponseToJSON, - ModelSettingUpdateRequestFromJSON, - ModelSettingUpdateRequestToJSON, - ModelSettingsResponseFromJSON, - ModelSettingsResponseToJSON, ModelUpdateScheduledTaskRequestFromJSON, ModelUpdateScheduledTaskRequestToJSON, PostgresqlDbGetAuditLogsRowFromJSON, @@ -77,6 +73,10 @@ import { PostgresqlDbSchedulerToJSON, SearchSearchCountRespFromJSON, SearchSearchCountRespToJSON, + SettingSettingUpdateRequestFromJSON, + SettingSettingUpdateRequestToJSON, + SettingSettingsResponseFromJSON, + SettingSettingsResponseToJSON, } from '../models'; export interface AddEmailConfigurationRequest { @@ -118,7 +118,7 @@ export interface UpdateScheduledTaskRequest { export interface UpdateSettingRequest { id: number; - modelSettingUpdateRequest?: ModelSettingUpdateRequest; + settingSettingUpdateRequest?: SettingSettingUpdateRequest; } export interface UploadAgentVersionRequest { @@ -325,13 +325,13 @@ export interface SettingsApiInterface { * @throws {RequiredError} * @memberof SettingsApiInterface */ - getSettingsRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; + getSettingsRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; /** * Get all settings * Get settings */ - getSettings(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + getSettings(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; /** * Get audit logs for all users @@ -432,7 +432,7 @@ export interface SettingsApiInterface { * Update setting * @summary Update setting * @param {number} id - * @param {ModelSettingUpdateRequest} [modelSettingUpdateRequest] + * @param {SettingSettingUpdateRequest} [settingSettingUpdateRequest] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof SettingsApiInterface @@ -945,7 +945,7 @@ export class SettingsApi extends runtime.BaseAPI implements SettingsApiInterface * Get all settings * Get settings */ - async getSettingsRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + async getSettingsRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -965,14 +965,14 @@ export class SettingsApi extends runtime.BaseAPI implements SettingsApiInterface query: queryParameters, }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(ModelSettingsResponseFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(SettingSettingsResponseFromJSON)); } /** * Get all settings * Get settings */ - async getSettings(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + async getSettings(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { const response = await this.getSettingsRaw(initOverrides); return await response.value(); } @@ -1236,7 +1236,7 @@ export class SettingsApi extends runtime.BaseAPI implements SettingsApiInterface method: 'PATCH', headers: headerParameters, query: queryParameters, - body: ModelSettingUpdateRequestToJSON(requestParameters.modelSettingUpdateRequest), + body: SettingSettingUpdateRequestToJSON(requestParameters.settingSettingUpdateRequest), }, initOverrides); return new runtime.VoidApiResponse(response); diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudCompliance.ts b/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudCompliance.ts index 46785a6183..fbc941d898 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudCompliance.ts +++ b/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudCompliance.ts @@ -159,7 +159,8 @@ export const ModelCloudComplianceComplianceCheckTypeEnum = { Nist: 'nist', Cis: 'cis', Soc2: 'soc_2', - NsaCisa: 'nsa-cisa' + NsaCisa: 'nsa-cisa', + AwsFoundationalSecurity: 'aws_foundational_security' } as const; export type ModelCloudComplianceComplianceCheckTypeEnum = typeof ModelCloudComplianceComplianceCheckTypeEnum[keyof typeof ModelCloudComplianceComplianceCheckTypeEnum]; diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudNodeAccountsListReq.ts b/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudNodeAccountsListReq.ts index 55fbbe2a29..d724b9c59e 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudNodeAccountsListReq.ts +++ b/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudNodeAccountsListReq.ts @@ -51,7 +51,8 @@ export const ModelCloudNodeAccountsListReqCloudProviderEnum = { Linux: 'linux', Kubernetes: 'kubernetes', AwsOrg: 'aws_org', - GcpOrg: 'gcp_org' + GcpOrg: 'gcp_org', + AzureOrg: 'azure_org' } as const; export type ModelCloudNodeAccountsListReqCloudProviderEnum = typeof ModelCloudNodeAccountsListReqCloudProviderEnum[keyof typeof ModelCloudNodeAccountsListReqCloudProviderEnum]; diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudNodeComplianceControl.ts b/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudNodeComplianceControl.ts index 5c486a67b2..5b927125d4 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudNodeComplianceControl.ts +++ b/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudNodeComplianceControl.ts @@ -25,6 +25,18 @@ export interface ModelCloudNodeComplianceControl { * @memberof ModelCloudNodeComplianceControl */ category_hierarchy?: Array | null; + /** + * + * @type {string} + * @memberof ModelCloudNodeComplianceControl + */ + category_hierarchy_short?: string; + /** + * + * @type {string} + * @memberof ModelCloudNodeComplianceControl + */ + compliance_type?: string; /** * * @type {string} @@ -43,6 +55,12 @@ export interface ModelCloudNodeComplianceControl { * @memberof ModelCloudNodeComplianceControl */ enabled?: boolean; + /** + * + * @type {string} + * @memberof ModelCloudNodeComplianceControl + */ + node_id?: string; /** * * @type {string} @@ -77,9 +95,12 @@ export function ModelCloudNodeComplianceControlFromJSONTyped(json: any, ignoreDi return { 'category_hierarchy': !exists(json, 'category_hierarchy') ? undefined : json['category_hierarchy'], + 'category_hierarchy_short': !exists(json, 'category_hierarchy_short') ? undefined : json['category_hierarchy_short'], + 'compliance_type': !exists(json, 'compliance_type') ? undefined : json['compliance_type'], 'control_id': !exists(json, 'control_id') ? undefined : json['control_id'], 'description': !exists(json, 'description') ? undefined : json['description'], 'enabled': !exists(json, 'enabled') ? undefined : json['enabled'], + 'node_id': !exists(json, 'node_id') ? undefined : json['node_id'], 'service': !exists(json, 'service') ? undefined : json['service'], 'title': !exists(json, 'title') ? undefined : json['title'], }; @@ -95,9 +116,12 @@ export function ModelCloudNodeComplianceControlToJSON(value?: ModelCloudNodeComp return { 'category_hierarchy': value.category_hierarchy, + 'category_hierarchy_short': value.category_hierarchy_short, + 'compliance_type': value.compliance_type, 'control_id': value.control_id, 'description': value.description, 'enabled': value.enabled, + 'node_id': value.node_id, 'service': value.service, 'title': value.title, }; diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudNodeControlReq.ts b/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudNodeControlReq.ts index 623a0fe596..28c8616c2d 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudNodeControlReq.ts +++ b/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelCloudNodeControlReq.ts @@ -62,7 +62,8 @@ export const ModelCloudNodeControlReqComplianceTypeEnum = { Nist: 'nist', Cis: 'cis', Soc2: 'soc_2', - NsaCisa: 'nsa-cisa' + NsaCisa: 'nsa-cisa', + AwsFoundationalSecurity: 'aws_foundational_security' } as const; export type ModelCloudNodeControlReqComplianceTypeEnum = typeof ModelCloudNodeControlReqComplianceTypeEnum[keyof typeof ModelCloudNodeControlReqComplianceTypeEnum]; diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelComplinaceScanResultsGroupReq.ts b/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelComplinaceScanResultsGroupReq.ts new file mode 100644 index 0000000000..c59854616c --- /dev/null +++ b/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelComplinaceScanResultsGroupReq.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Deepfence ThreatMapper + * Deepfence Runtime API provides programmatic control over Deepfence microservice securing your container, kubernetes and cloud deployments. The API abstracts away underlying infrastructure details like cloud provider, container distros, container orchestrator and type of deployment. This is one uniform API to manage and control security alerts, policies and response to alerts for microservices running anywhere i.e. managed pure greenfield container deployments or a mix of containers, VMs and serverless paradigms like AWS Fargate. + * + * The version of the OpenAPI document: v2.2.1 + * Contact: community@deepfence.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { ReportersFieldsFilters } from './ReportersFieldsFilters'; +import { + ReportersFieldsFiltersFromJSON, + ReportersFieldsFiltersFromJSONTyped, + ReportersFieldsFiltersToJSON, +} from './ReportersFieldsFilters'; + +/** + * + * @export + * @interface ModelComplinaceScanResultsGroupReq + */ +export interface ModelComplinaceScanResultsGroupReq { + /** + * + * @type {ReportersFieldsFilters} + * @memberof ModelComplinaceScanResultsGroupReq + */ + fields_filter: ReportersFieldsFilters; + /** + * + * @type {string} + * @memberof ModelComplinaceScanResultsGroupReq + */ + scan_id: string; +} + +/** + * Check if a given object implements the ModelComplinaceScanResultsGroupReq interface. + */ +export function instanceOfModelComplinaceScanResultsGroupReq(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "fields_filter" in value; + isInstance = isInstance && "scan_id" in value; + + return isInstance; +} + +export function ModelComplinaceScanResultsGroupReqFromJSON(json: any): ModelComplinaceScanResultsGroupReq { + return ModelComplinaceScanResultsGroupReqFromJSONTyped(json, false); +} + +export function ModelComplinaceScanResultsGroupReqFromJSONTyped(json: any, ignoreDiscriminator: boolean): ModelComplinaceScanResultsGroupReq { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'fields_filter': ReportersFieldsFiltersFromJSON(json['fields_filter']), + 'scan_id': json['scan_id'], + }; +} + +export function ModelComplinaceScanResultsGroupReqToJSON(value?: ModelComplinaceScanResultsGroupReq | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'fields_filter': ReportersFieldsFiltersToJSON(value.fields_filter), + 'scan_id': value.scan_id, + }; +} + diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelComplinaceScanResultsGroupResp.ts b/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelComplinaceScanResultsGroupResp.ts new file mode 100644 index 0000000000..e837cf24f5 --- /dev/null +++ b/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelComplinaceScanResultsGroupResp.ts @@ -0,0 +1,65 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Deepfence ThreatMapper + * Deepfence Runtime API provides programmatic control over Deepfence microservice securing your container, kubernetes and cloud deployments. The API abstracts away underlying infrastructure details like cloud provider, container distros, container orchestrator and type of deployment. This is one uniform API to manage and control security alerts, policies and response to alerts for microservices running anywhere i.e. managed pure greenfield container deployments or a mix of containers, VMs and serverless paradigms like AWS Fargate. + * + * The version of the OpenAPI document: v2.2.1 + * Contact: community@deepfence.io + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ModelComplinaceScanResultsGroupResp + */ +export interface ModelComplinaceScanResultsGroupResp { + /** + * + * @type {{ [key: string]: { [key: string]: number; }; }} + * @memberof ModelComplinaceScanResultsGroupResp + */ + groups?: { [key: string]: { [key: string]: number; }; } | null; +} + +/** + * Check if a given object implements the ModelComplinaceScanResultsGroupResp interface. + */ +export function instanceOfModelComplinaceScanResultsGroupResp(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function ModelComplinaceScanResultsGroupRespFromJSON(json: any): ModelComplinaceScanResultsGroupResp { + return ModelComplinaceScanResultsGroupRespFromJSONTyped(json, false); +} + +export function ModelComplinaceScanResultsGroupRespFromJSONTyped(json: any, ignoreDiscriminator: boolean): ModelComplinaceScanResultsGroupResp { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'groups': !exists(json, 'groups') ? undefined : json['groups'], + }; +} + +export function ModelComplinaceScanResultsGroupRespToJSON(value?: ModelComplinaceScanResultsGroupResp | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'groups': value.groups, + }; +} + diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelSettingUpdateRequest.ts b/deepfence_frontend/apps/dashboard/src/api/generated/models/SettingSettingUpdateRequest.ts similarity index 64% rename from deepfence_frontend/apps/dashboard/src/api/generated/models/ModelSettingUpdateRequest.ts rename to deepfence_frontend/apps/dashboard/src/api/generated/models/SettingSettingUpdateRequest.ts index 9df16f3603..58a4a75920 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelSettingUpdateRequest.ts +++ b/deepfence_frontend/apps/dashboard/src/api/generated/models/SettingSettingUpdateRequest.ts @@ -16,19 +16,19 @@ import { exists, mapValues } from '../runtime'; /** * * @export - * @interface ModelSettingUpdateRequest + * @interface SettingSettingUpdateRequest */ -export interface ModelSettingUpdateRequest { +export interface SettingSettingUpdateRequest { /** * * @type {string} - * @memberof ModelSettingUpdateRequest + * @memberof SettingSettingUpdateRequest */ - key: ModelSettingUpdateRequestKeyEnum; + key: SettingSettingUpdateRequestKeyEnum; /** * * @type {string} - * @memberof ModelSettingUpdateRequest + * @memberof SettingSettingUpdateRequest */ value: string; } @@ -37,18 +37,18 @@ export interface ModelSettingUpdateRequest { /** * @export */ -export const ModelSettingUpdateRequestKeyEnum = { +export const SettingSettingUpdateRequestKeyEnum = { ConsoleUrl: 'console_url', FileServerUrl: 'file_server_url', InactiveDeleteScanResults: 'inactive_delete_scan_results' } as const; -export type ModelSettingUpdateRequestKeyEnum = typeof ModelSettingUpdateRequestKeyEnum[keyof typeof ModelSettingUpdateRequestKeyEnum]; +export type SettingSettingUpdateRequestKeyEnum = typeof SettingSettingUpdateRequestKeyEnum[keyof typeof SettingSettingUpdateRequestKeyEnum]; /** - * Check if a given object implements the ModelSettingUpdateRequest interface. + * Check if a given object implements the SettingSettingUpdateRequest interface. */ -export function instanceOfModelSettingUpdateRequest(value: object): boolean { +export function instanceOfSettingSettingUpdateRequest(value: object): boolean { let isInstance = true; isInstance = isInstance && "key" in value; isInstance = isInstance && "value" in value; @@ -56,11 +56,11 @@ export function instanceOfModelSettingUpdateRequest(value: object): boolean { return isInstance; } -export function ModelSettingUpdateRequestFromJSON(json: any): ModelSettingUpdateRequest { - return ModelSettingUpdateRequestFromJSONTyped(json, false); +export function SettingSettingUpdateRequestFromJSON(json: any): SettingSettingUpdateRequest { + return SettingSettingUpdateRequestFromJSONTyped(json, false); } -export function ModelSettingUpdateRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): ModelSettingUpdateRequest { +export function SettingSettingUpdateRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): SettingSettingUpdateRequest { if ((json === undefined) || (json === null)) { return json; } @@ -71,7 +71,7 @@ export function ModelSettingUpdateRequestFromJSONTyped(json: any, ignoreDiscrimi }; } -export function ModelSettingUpdateRequestToJSON(value?: ModelSettingUpdateRequest | null): any { +export function SettingSettingUpdateRequestToJSON(value?: SettingSettingUpdateRequest | null): any { if (value === undefined) { return undefined; } diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelSettingsResponse.ts b/deepfence_frontend/apps/dashboard/src/api/generated/models/SettingSettingsResponse.ts similarity index 72% rename from deepfence_frontend/apps/dashboard/src/api/generated/models/ModelSettingsResponse.ts rename to deepfence_frontend/apps/dashboard/src/api/generated/models/SettingSettingsResponse.ts index 8190aece9d..70b6f6f0dc 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/models/ModelSettingsResponse.ts +++ b/deepfence_frontend/apps/dashboard/src/api/generated/models/SettingSettingsResponse.ts @@ -16,45 +16,45 @@ import { exists, mapValues } from '../runtime'; /** * * @export - * @interface ModelSettingsResponse + * @interface SettingSettingsResponse */ -export interface ModelSettingsResponse { +export interface SettingSettingsResponse { /** * * @type {string} - * @memberof ModelSettingsResponse + * @memberof SettingSettingsResponse */ description: string; /** * * @type {number} - * @memberof ModelSettingsResponse + * @memberof SettingSettingsResponse */ id: number; /** * * @type {string} - * @memberof ModelSettingsResponse + * @memberof SettingSettingsResponse */ key: string; /** * * @type {string} - * @memberof ModelSettingsResponse + * @memberof SettingSettingsResponse */ label: string; /** * * @type {any} - * @memberof ModelSettingsResponse + * @memberof SettingSettingsResponse */ value: any | null; } /** - * Check if a given object implements the ModelSettingsResponse interface. + * Check if a given object implements the SettingSettingsResponse interface. */ -export function instanceOfModelSettingsResponse(value: object): boolean { +export function instanceOfSettingSettingsResponse(value: object): boolean { let isInstance = true; isInstance = isInstance && "description" in value; isInstance = isInstance && "id" in value; @@ -65,11 +65,11 @@ export function instanceOfModelSettingsResponse(value: object): boolean { return isInstance; } -export function ModelSettingsResponseFromJSON(json: any): ModelSettingsResponse { - return ModelSettingsResponseFromJSONTyped(json, false); +export function SettingSettingsResponseFromJSON(json: any): SettingSettingsResponse { + return SettingSettingsResponseFromJSONTyped(json, false); } -export function ModelSettingsResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): ModelSettingsResponse { +export function SettingSettingsResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): SettingSettingsResponse { if ((json === undefined) || (json === null)) { return json; } @@ -83,7 +83,7 @@ export function ModelSettingsResponseFromJSONTyped(json: any, ignoreDiscriminato }; } -export function ModelSettingsResponseToJSON(value?: ModelSettingsResponse | null): any { +export function SettingSettingsResponseToJSON(value?: SettingSettingsResponse | null): any { if (value === undefined) { return undefined; } diff --git a/deepfence_frontend/apps/dashboard/src/api/generated/models/index.ts b/deepfence_frontend/apps/dashboard/src/api/generated/models/index.ts index 811a434610..8ac6a1147c 100644 --- a/deepfence_frontend/apps/dashboard/src/api/generated/models/index.ts +++ b/deepfence_frontend/apps/dashboard/src/api/generated/models/index.ts @@ -76,6 +76,8 @@ export * from './ModelComplianceScanInfo'; export * from './ModelComplianceScanResult'; export * from './ModelComplianceScanStatusResp'; export * from './ModelComplianceScanTriggerReq'; +export * from './ModelComplinaceScanResultsGroupReq'; +export * from './ModelComplinaceScanResultsGroupResp'; export * from './ModelConnection'; export * from './ModelContainer'; export * from './ModelContainerImage'; @@ -169,8 +171,6 @@ export * from './ModelSecretRule'; export * from './ModelSecretScanResult'; export * from './ModelSecretScanResultRules'; export * from './ModelSecretScanTriggerReq'; -export * from './ModelSettingUpdateRequest'; -export * from './ModelSettingsResponse'; export * from './ModelStopScanRequest'; export * from './ModelSummary'; export * from './ModelTopologyDeltaReq'; @@ -204,6 +204,8 @@ export * from './SearchSearchCountResp'; export * from './SearchSearchFilter'; export * from './SearchSearchNodeReq'; export * from './SearchSearchScanReq'; +export * from './SettingSettingUpdateRequest'; +export * from './SettingSettingsResponse'; export * from './UtilsAdvancedReportFilters'; export * from './UtilsReportFilters'; export * from './UtilsReportOptions'; diff --git a/deepfence_frontend/apps/dashboard/src/components/forms/SearchableCloudAccountsList.tsx b/deepfence_frontend/apps/dashboard/src/components/forms/SearchableCloudAccountsList.tsx index 16b61ce34a..9f904e0588 100644 --- a/deepfence_frontend/apps/dashboard/src/components/forms/SearchableCloudAccountsList.tsx +++ b/deepfence_frontend/apps/dashboard/src/components/forms/SearchableCloudAccountsList.tsx @@ -4,10 +4,10 @@ import { Suspense, useEffect, useMemo, useState } from 'react'; import { CircleSpinner, Combobox, ComboboxOption } from 'ui-components'; import { queries } from '@/queries'; +import { CloudNodeType } from '@/types/common'; -export type ICloudAccountType = 'gcp' | 'aws' | 'azure' | 'aws_org' | 'gcp_org'; export type SearchableCloudAccountsListProps = { - cloudProvider?: ICloudAccountType; + cloudProvider?: CloudNodeType; onChange?: (value: string[]) => void; onClearAll?: () => void; defaultSelectedAccounts?: string[]; @@ -88,10 +88,10 @@ const SearchableCloudAccounts = ({ isSelectVariantType && selectedAccounts.length > 0 ? `${selectedAccounts.length} selected` : cloudProvider + ? displayValue ? displayValue - ? displayValue - : `${cloudProvider} account` - : 'Cloud account' + : `${cloudProvider} account` + : 'Cloud account' } multiple value={selectedAccounts} @@ -147,8 +147,8 @@ export const SearchableCloudAccountsList = (props: SearchableCloudAccountsListPr return displayValue ? displayValue : cloudProvider - ? `${cloudProvider} account` - : 'Cloud account'; + ? `${cloudProvider} account` + : 'Cloud account'; }} multiple onQueryChange={() => { diff --git a/deepfence_frontend/apps/dashboard/src/components/icons/posture/index.tsx b/deepfence_frontend/apps/dashboard/src/components/icons/posture/index.tsx index 0cd3daca72..ed470aac5b 100644 --- a/deepfence_frontend/apps/dashboard/src/components/icons/posture/index.tsx +++ b/deepfence_frontend/apps/dashboard/src/components/icons/posture/index.tsx @@ -1,3 +1,4 @@ +import { ModelCloudNodeAccountsListReqCloudProviderEnum } from '@/api/generated'; import { ShieldCheckSolidIcon } from '@/components/icons/posture/ShieldCheckSolid'; import { ShieldWarningSolidIcon } from '@/components/icons/posture/ShieldWarningSolid'; import { ShieldXSolidIcon } from '@/components/icons/posture/ShieldXSolid'; @@ -10,19 +11,21 @@ import { KubernetesIcon } from './Kubernetes'; import { LinuxIcon } from './Linux'; export const PostureLogos = ({ name }: { name: string }) => { - if (name === 'aws') { + if (name === ModelCloudNodeAccountsListReqCloudProviderEnum.Aws) { return ; - } else if (name === 'aws_org') { + } else if (name === ModelCloudNodeAccountsListReqCloudProviderEnum.AwsOrg) { return ; - } else if (name === 'azure') { + } else if (name === ModelCloudNodeAccountsListReqCloudProviderEnum.Azure) { return ; - } else if (name === 'gcp_org') { + } else if (name === ModelCloudNodeAccountsListReqCloudProviderEnum.GcpOrg) { return ; - } else if (name === 'gcp') { + } else if (name === ModelCloudNodeAccountsListReqCloudProviderEnum.AzureOrg) { + return ; + } else if (name === ModelCloudNodeAccountsListReqCloudProviderEnum.Gcp) { return ; - } else if (name === 'kubernetes') { + } else if (name === ModelCloudNodeAccountsListReqCloudProviderEnum.Kubernetes) { return ; - } else if (name === 'linux') { + } else if (name === ModelCloudNodeAccountsListReqCloudProviderEnum.Linux) { return ; } return null; diff --git a/deepfence_frontend/apps/dashboard/src/components/scan-configure-forms/ComplianceScanConfigureForm.tsx b/deepfence_frontend/apps/dashboard/src/components/scan-configure-forms/ComplianceScanConfigureForm.tsx index 1ada4c361a..0ad0e80e8a 100644 --- a/deepfence_frontend/apps/dashboard/src/components/scan-configure-forms/ComplianceScanConfigureForm.tsx +++ b/deepfence_frontend/apps/dashboard/src/components/scan-configure-forms/ComplianceScanConfigureForm.tsx @@ -15,6 +15,7 @@ import { CircleSpinner, createColumnHelper, Switch, Table } from 'ui-components' import { getComplianceApiClient, getSettingsApiClient } from '@/api/api'; import { ModelBenchmarkType, + ModelCloudNodeAccountsListReqCloudProviderEnum, ModelComplianceScanTriggerReq, ModelNodeIdentifierNodeTypeEnum, ModelScanResultsActionRequestScanTypeEnum, @@ -23,8 +24,13 @@ import { ModelCloudNodeComplianceControl } from '@/api/generated/models/ModelClo import { ScheduleScanForm } from '@/components/scan-configure-forms/ScheduleScanForm'; import { TruncatedText } from '@/components/TruncatedText'; import { ActionEnumType } from '@/features/postures/data-component/toggleControlApiAction'; +import { + isCloudNonOrgNode, + isCloudOrgNode, + isNonCloudNode, +} from '@/features/postures/utils'; import { invalidateAllQueries, queries } from '@/queries'; -import { ComplianceScanNodeTypeEnum, isCloudNode, isCloudOrgNode } from '@/types/common'; +import { ComplianceScanNodeTypeEnum } from '@/types/common'; import { get403Message, getResponseErrors } from '@/utils/403'; import { apiWrapper } from '@/utils/api'; import { getBenchmarkPrettyName } from '@/utils/enum'; @@ -51,6 +57,7 @@ export const complianceType: { gcp: [ModelBenchmarkType.Cis], gcp_org: [ModelBenchmarkType.Cis], azure: [ModelBenchmarkType.Cis, ModelBenchmarkType.Nist, ModelBenchmarkType.Hipaa], + azure_org: [ModelBenchmarkType.Cis, ModelBenchmarkType.Nist, ModelBenchmarkType.Hipaa], host: [ ModelBenchmarkType.Hipaa, ModelBenchmarkType.Gdpr, @@ -89,14 +96,6 @@ type TabsType = { value: ModelBenchmarkType; }; -export const CLOUDS = [ - ComplianceScanNodeTypeEnum.aws, - ComplianceScanNodeTypeEnum.aws_org, - ComplianceScanNodeTypeEnum.azure, - ComplianceScanNodeTypeEnum.gcp, - ComplianceScanNodeTypeEnum.gcp_org, -]; - const isKubernetesNode = (nodeType: ComplianceScanNodeTypeEnum) => nodeType == ComplianceScanNodeTypeEnum.kubernetes_cluster; @@ -109,7 +108,8 @@ export const scanPostureApiAction = async ({ let nodeType = body._nodeType.toString(); const checkTypes = body._checkTypes.toString()?.split(',') as Array; - const isCloudScan = CLOUDS.includes(nodeType as ComplianceScanNodeTypeEnum); + const isCloudScan = !isNonCloudNode(nodeType); + if (isKubernetesNode(nodeType as ComplianceScanNodeTypeEnum)) { nodeType = 'cluster'; } else if (isCloudScan) { @@ -332,19 +332,20 @@ const ControlTable = ({ const _nodeType = useMemo(() => { switch (nodeType) { case ComplianceScanNodeTypeEnum.host: - return 'linux'; + return ModelCloudNodeAccountsListReqCloudProviderEnum.Linux; case ComplianceScanNodeTypeEnum.kubernetes_cluster: - return 'kubernetes'; - case ComplianceScanNodeTypeEnum.aws_org: - return ComplianceScanNodeTypeEnum.aws; - case ComplianceScanNodeTypeEnum.gcp_org: - return ComplianceScanNodeTypeEnum.gcp; + return ModelCloudNodeAccountsListReqCloudProviderEnum.Kubernetes; + case ModelCloudNodeAccountsListReqCloudProviderEnum.AwsOrg: + return ModelCloudNodeAccountsListReqCloudProviderEnum.Aws; + case ModelCloudNodeAccountsListReqCloudProviderEnum.GcpOrg: + return ModelCloudNodeAccountsListReqCloudProviderEnum.Gcp; + case ModelCloudNodeAccountsListReqCloudProviderEnum.AzureOrg: + return ModelCloudNodeAccountsListReqCloudProviderEnum.Azure; default: return nodeType; } }, [nodeType]); - const fetcher = useFetcher(); const [pageSize, setPageSize] = useState(10); const { data } = useGetControls({ checkType: selectedTab, @@ -566,7 +567,7 @@ export const ComplianceScanConfigureForm = ({ ) : null} - {!isCloudNode(nodeType) && + {!isCloudNonOrgNode(nodeType) && !isCloudOrgNode(nodeType) && !isKubernetesNode(nodeType) ? (
diff --git a/deepfence_frontend/apps/dashboard/src/features/integrations/components/report-form/AdvanceFilter.tsx b/deepfence_frontend/apps/dashboard/src/features/integrations/components/report-form/AdvanceFilter.tsx index 738388a9f5..942870f242 100644 --- a/deepfence_frontend/apps/dashboard/src/features/integrations/components/report-form/AdvanceFilter.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/integrations/components/report-form/AdvanceFilter.tsx @@ -3,6 +3,7 @@ import { useMemo, useState } from 'react'; import { Listbox, ListboxOption } from 'ui-components'; import { + ModelCloudNodeAccountsListReqCloudProviderEnum, UtilsReportFiltersNodeTypeEnum, UtilsReportFiltersScanTypeEnum, } from '@/api/generated'; @@ -11,7 +12,8 @@ import { SearchableClusterList } from '@/components/forms/SearchableClusterList' import { SearchableContainerList } from '@/components/forms/SearchableContainerList'; import { SearchableHostList } from '@/components/forms/SearchableHostList'; import { SearchableImageList } from '@/components/forms/SearchableImageList'; -import { isCloudNode, ScanTypeEnum } from '@/types/common'; +import { isCloudNonOrgNode, isCloudOrgNode } from '@/features/postures/utils'; +import { ScanTypeEnum } from '@/types/common'; const getNodeTypeByProviderName = (providerName: string): string | undefined => { switch (providerName) { @@ -67,6 +69,10 @@ export const AdvancedFilter = ({ const [images, setImages] = useState([]); const [containers, setContainers] = useState([]); + const isCloudNode = (nodeType: string) => + isCloudNonOrgNode(nodeType as ModelCloudNodeAccountsListReqCloudProviderEnum) || + isCloudOrgNode(nodeType as ModelCloudNodeAccountsListReqCloudProviderEnum); + return ( <> {resourceType && provider ? ( @@ -75,7 +81,7 @@ export const AdvancedFilter = ({
Advanced Filter (Optional)
- {isCloudNode(nodeType) && ( + {nodeType && isCloudNode(nodeType) && ( {
)} - {ACCOUNT_CONNECTOR.AZURE === account && } + {account.startsWith(ACCOUNT_CONNECTOR.AZURE) && } {account.startsWith(ACCOUNT_CONNECTOR.GCP) && } ); diff --git a/deepfence_frontend/apps/dashboard/src/features/postures/pages/Accounts.tsx b/deepfence_frontend/apps/dashboard/src/features/postures/pages/Accounts.tsx index 9118b88f0d..2199285c50 100644 --- a/deepfence_frontend/apps/dashboard/src/features/postures/pages/Accounts.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/postures/pages/Accounts.tsx @@ -37,16 +37,14 @@ import { getCloudNodesApiClient, getScanResultsApiClient } from '@/api/api'; import { ModelBulkDeleteScansRequestScanTypeEnum, ModelCloudNodeAccountInfo, + ModelCloudNodeAccountsListReqCloudProviderEnum, UtilsReportFiltersNodeTypeEnum, UtilsReportFiltersScanTypeEnum, } from '@/api/generated'; import { ConfigureScanModal } from '@/components/ConfigureScanModal'; import { DFLink } from '@/components/DFLink'; import { FilterBadge } from '@/components/filters/FilterBadge'; -import { - ICloudAccountType, - SearchableCloudAccountsList, -} from '@/components/forms/SearchableCloudAccountsList'; +import { SearchableCloudAccountsList } from '@/components/forms/SearchableCloudAccountsList'; import { SearchableClusterList } from '@/components/forms/SearchableClusterList'; import { SearchableHostList } from '@/components/forms/SearchableHostList'; import { ArrowUpCircleLine } from '@/components/icons/common/ArrowUpCircleLine'; @@ -57,10 +55,7 @@ import { PlusIcon } from '@/components/icons/common/Plus'; import { RefreshIcon } from '@/components/icons/common/Refresh'; import { TimesIcon } from '@/components/icons/common/Times'; import { TrashLineIcon } from '@/components/icons/common/TrashLine'; -import { - CLOUDS, - ComplianceScanConfigureFormProps, -} from '@/components/scan-configure-forms/ComplianceScanConfigureForm'; +import { ComplianceScanConfigureFormProps } from '@/components/scan-configure-forms/ComplianceScanConfigureForm'; import { StopScanForm } from '@/components/scan-configure-forms/StopScanForm'; import { ScanStatusBadge } from '@/components/ScanStatusBadge'; import { PostureIcon } from '@/components/sideNavigation/icons/Posture'; @@ -68,19 +63,24 @@ import { getColorForCompliancePercent } from '@/constants/charts'; import { BreadcrumbWrapper } from '@/features/common/BreadcrumbWrapper'; import { useDownloadScan } from '@/features/common/data-component/downloadScanAction'; import { FilterWrapper } from '@/features/common/FilterWrapper'; +import { providersToNameMapping } from '@/features/postures/pages/Posture'; import { - isKubernetesProvider, - isLinuxProvider, - isNonCloudProvider, - providersToNameMapping, -} from '@/features/postures/pages/Posture'; + getDeleteConfirmationDisplayName, + getDisplayNameOfNodeType, + getSearchableCloudAccountDisplayName, + isCloudNonOrgNode, + isCloudOrgNode, + isKubernetesNodeType, + isLinuxNodeType, + isNonCloudNode, +} from '@/features/postures/utils'; import { SuccessModalContent } from '@/features/settings/components/SuccessModalContent'; import { invalidateAllQueries, queries } from '@/queries'; import { useTheme } from '@/theme/ThemeContext'; import { + CloudNodeNonOrgType, + CloudNodeType, ComplianceScanNodeTypeEnum, - isCloudNode, - isCloudOrgNode, ScanTypeEnum, } from '@/types/common'; import { get403Message, getResponseErrors } from '@/utils/403'; @@ -126,6 +126,8 @@ const getNodeTypeByProviderName = (providerName: string): ComplianceScanNodeType return ComplianceScanNodeTypeEnum.gcp_org; case 'azure': return ComplianceScanNodeTypeEnum.azure; + case 'azure_org': + return ComplianceScanNodeTypeEnum.azure_org; case 'kubernetes': return ComplianceScanNodeTypeEnum.kubernetes_cluster; default: @@ -305,10 +307,10 @@ const FILTER_SEARCHPARAMS_DYNAMIC_KEYS = [ const FILTER_SEARCHPARAMS: Record = { complianceScanStatus: 'Posture scan status', status: 'Status', - org_accounts: 'Organization accounts', + org_accounts: 'Organization account', aws_accounts: 'Account', gcp_accounts: 'Account', - azure_accounts: 'Account', + azure_accounts: 'Subscription', hosts: 'Account', clusters: 'Account', }; @@ -320,7 +322,7 @@ const getAppliedFiltersCount = (searchParams: URLSearchParams) => { }; const Filters = () => { const { nodeType } = useParams() as { - nodeType: 'aws' | 'gcp' | 'azure'; + nodeType: string; }; const [searchParams, setSearchParams] = useSearchParams(); @@ -420,56 +422,61 @@ const Filters = () => { ); })} - {(nodeType === 'aws' || nodeType === 'gcp') && ( - { - setSearchParams((prev) => { - prev.delete('org_accounts'); - prev.delete('page'); - return prev; - }); - }} - onChange={(value) => { - setSearchParams((prev) => { - prev.delete('org_accounts'); - value.forEach((id) => { - prev.append('org_accounts', id); + {isCloudNonOrgNode(nodeType) ? ( + <> + { + setSearchParams((prev) => { + prev.delete('org_accounts'); + prev.delete('page'); + return prev; }); - prev.delete('page'); - return prev; - }); - }} - /> - )} - {isCloudNode(nodeType) ? ( - { - setSearchParams((prev) => { - prev.delete(`${nodeType}_accounts`); - prev.delete('page'); - return prev; - }); - }} - onChange={(value) => { - setSearchParams((prev) => { - prev.delete(`${nodeType}_accounts`); - value.forEach((id) => { - prev.append(`${nodeType}_accounts`, id); + }} + onChange={(value) => { + setSearchParams((prev) => { + prev.delete('org_accounts'); + value.forEach((id) => { + prev.append('org_accounts', id); + }); + prev.delete('page'); + return prev; }); - prev.delete('page'); - return prev; - }); - }} - /> + }} + /> + { + setSearchParams((prev) => { + prev.delete(`${nodeType}_accounts`); + prev.delete('page'); + return prev; + }); + }} + onChange={(value) => { + setSearchParams((prev) => { + prev.delete(`${nodeType}_accounts`); + value.forEach((id) => { + prev.append(`${nodeType}_accounts`, id); + }); + prev.delete('page'); + return prev; + }); + }} + /> + ) : null} - {isLinuxProvider(nodeType) ? ( + + {isLinuxNodeType(nodeType) ? ( { }} /> ) : null} - {isKubernetesProvider(nodeType) ? ( + {isKubernetesNodeType(nodeType) ? ( { return Object.keys(FILTER_SEARCHPARAMS).includes(key); }) as Array<[FILTER_SEARCHPARAMS_KEYS_ENUM, string]> ).map(([key, value]) => { + if (key === FILTER_SEARCHPARAMS_KEYS_ENUM.org_accounts) { + return ( + + ); + } + if (FILTER_SEARCHPARAMS_DYNAMIC_KEYS.includes(key)) { return ( void; }) => { const fetcher = useFetcher(); - const params = useParams(); + const params = useParams() as { + nodeType: string; + }; const onDeleteAction = useCallback( (actionType: string) => { @@ -715,7 +737,10 @@ const DeleteAccountConfirmationModal = ({ - Delete account + Delete{' '} + {getDisplayNameOfNodeType( + params.nodeType as ModelCloudNodeAccountsListReqCloudProviderEnum, + )} ) : undefined } @@ -749,12 +774,9 @@ const DeleteAccountConfirmationModal = ({ {!fetcher.data?.success ? (
- {isCloudNode(params.nodeType) - ? `The Selected cloud account, resources and scans related to the account will be - deleted.` - : isCloudOrgNode(params.nodeType) - ? `The Selected org cloud account, child accounts related to org account, resources and scans related to the cloud accounts will be deleted.` - : ''} + {getDeleteConfirmationDisplayName( + params.nodeType as ModelCloudNodeAccountsListReqCloudProviderEnum, + )}
Are you sure you want to delete? @@ -877,7 +899,10 @@ const ActionDropdown = ({ onTableAction(row, ActionEnumType.REFRESH_ACCOUNT); }} > - Refresh account + Refresh{' '} + {getDisplayNameOfNodeType( + nodeType as ModelCloudNodeAccountsListReqCloudProviderEnum, + ).toLowerCase()} - Delete account + Delete{' '} + {getDisplayNameOfNodeType( + nodeType as ModelCloudNodeAccountsListReqCloudProviderEnum, + ).toLowerCase()} ) : null} @@ -985,7 +1013,10 @@ const BulkActions = ({ ); }} > - ADD NEW ACCOUNT + ADD NEW{' '} + {getDisplayNameOfNodeType( + nodeType as ModelCloudNodeAccountsListReqCloudProviderEnum, + ).toUpperCase()} ) : null} @@ -1198,9 +1235,14 @@ const AccountTable = ({ let path = '/posture/scan-results/:nodeType/:scanId'; if ( - cell.row.original.cloud_provider && - CLOUDS.includes( - cell.row.original.cloud_provider as ComplianceScanNodeTypeEnum, + (cell.row.original.cloud_provider && + isCloudNode( + cell.row.original + .cloud_provider as ModelCloudNodeAccountsListReqCloudProviderEnum, + )) || + isCloudOrgNode( + cell.row.original + .cloud_provider as ModelCloudNodeAccountsListReqCloudProviderEnum, ) ) { path = '/posture/cloud/scan-results/:nodeType/:scanId'; @@ -1224,7 +1266,10 @@ const AccountTable = ({ ); }, - header: () => 'Account', + header: () => + getDisplayNameOfNodeType( + nodeType as ModelCloudNodeAccountsListReqCloudProviderEnum, + ), ...columnWidth.node_name, }), columnHelper.accessor('compliance_percentage', { @@ -1289,7 +1334,7 @@ const AccountTable = ({ }), ]; - if (isCloudNode(nodeType) || isCloudOrgNode(nodeType)) { + if (isCloudNonOrgNode(nodeType) || isCloudOrgNode(nodeType)) { columns.push( columnHelper.accessor('version', { enableSorting: false, @@ -1471,7 +1516,7 @@ const Accounts = () => { const [showCancelScan, setShowCancelScan] = useState(false); const [openStartScan, setOpenStartScan] = useState(false); - const scanType = isNonCloudProvider(routeParams.nodeType) + const scanType = isNonCloudNode(routeParams.nodeType) ? ScanTypeEnum.ComplianceScan : ScanTypeEnum.CloudComplianceScan; @@ -1587,7 +1632,7 @@ const Accounts = () => { return (
- {!hasOrgCloudAccount(nodeType ?? '') ?
: null} + {!isCloudNode(nodeType ?? '') ?
: null} {showCancelScan && ( { showDialog={showDeleteDialog} scanIds={rowToAction.scanIdsToDeleteScan} scanType={ - isNonCloudProvider(routeParams.nodeType) + isNonCloudNode(routeParams.nodeType) ? ModelBulkDeleteScansRequestScanTypeEnum.Compliance : ModelBulkDeleteScansRequestScanTypeEnum.CloudCompliance } @@ -1684,16 +1729,18 @@ const Accounts = () => { ); }; -const tabs = [ - { - label: 'Regular Accounts', - value: 'accounts', - }, - { - label: 'Organization Accounts', - value: 'org-accounts', - }, -]; +const tabs = ['accounts', 'org-accounts'] as const; + +function getTabLabel(value: (typeof tabs)[number], nodeType: string) { + if (nodeType?.includes?.('azure')) { + if (value === 'accounts') { + return 'Subscriptions'; + } else { + return 'Tenants'; + } + } + return value === 'accounts' ? 'Regular Accounts' : 'Organization Accounts'; +} const AccountWithTab = () => { const { nodeType } = useParams() as { @@ -1705,13 +1752,20 @@ const AccountWithTab = () => { }); const { navigate } = usePageNavigation(); + const tabOpts = tabs.map((tab) => { + return { + label: getTabLabel(tab, nodeType), + value: tab, + }; + }); + return ( <>
{ if (currentTab === value) return; let _nodeType = nodeType; @@ -1742,15 +1796,15 @@ const ConditionalAccount = () => { nodeType: string; }; - if (hasOrgCloudAccount(nodeType)) { + if (isCloudNode(nodeType)) { return ; } return ; }; -const hasOrgCloudAccount = (nodeType: string) => { - return nodeType.startsWith('aws') || nodeType.startsWith('gcp'); -}; +const isCloudNode = (nodeType: string) => + isCloudNonOrgNode(nodeType as ModelCloudNodeAccountsListReqCloudProviderEnum) || + isCloudOrgNode(nodeType as ModelCloudNodeAccountsListReqCloudProviderEnum); export const module = { action, diff --git a/deepfence_frontend/apps/dashboard/src/features/postures/pages/Posture.tsx b/deepfence_frontend/apps/dashboard/src/features/postures/pages/Posture.tsx index 451540eecb..a62d43cb2d 100644 --- a/deepfence_frontend/apps/dashboard/src/features/postures/pages/Posture.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/postures/pages/Posture.tsx @@ -3,12 +3,20 @@ import { Suspense } from 'react'; import { cn } from 'tailwind-preset'; import { Breadcrumb, BreadcrumbLink, Card, Separator } from 'ui-components'; -import { ModelPostureProvider } from '@/api/generated'; +import { + ModelCloudNodeAccountsListReqCloudProviderEnum, + ModelPostureProvider, +} from '@/api/generated'; import { DFLink } from '@/components/DFLink'; import { ComplianceIconByPercent, PostureLogos } from '@/components/icons/posture'; import { PostureIcon } from '@/components/sideNavigation/icons/Posture'; import { getColorForCompliancePercent } from '@/constants/charts'; import { BreadcrumbWrapper } from '@/features/common/BreadcrumbWrapper'; +import { + isKubernetesNodeType, + isLinuxNodeType, + isNonCloudNode, +} from '@/features/postures/utils'; import { queries } from '@/queries'; import { useTheme } from '@/theme/ThemeContext'; import { abbreviateNumber, formatPercentage } from '@/utils/number'; @@ -18,17 +26,12 @@ export const providersToNameMapping: { [key: string]: string } = { aws_org: 'AWS Organizations', gcp: 'GCP', gcp_org: 'GCP Organizations', + azure_org: 'Azure', azure: 'Azure', linux: 'Linux Hosts', kubernetes: 'Kubernetes', }; -export const isNonCloudProvider = (provider: string) => { - return provider === 'linux' || provider === 'kubernetes'; -}; -export const isLinuxProvider = (provider: string) => provider === 'linux'; -export const isKubernetesProvider = (provider: string) => provider === 'kubernetes'; - const HeaderSkeleton = () => { return (
@@ -147,56 +150,41 @@ const CardIconSection = ({ provider }: { provider: ModelPostureProvider }) => { ); }; +function getAccountProductName(provider: ModelPostureProvider) { + if (isLinuxNodeType(provider.name ?? '')) { + return 'Hosts'; + } else if (isKubernetesNodeType(provider.name ?? '')) { + return 'Clusters'; + } else if (provider.name === ModelCloudNodeAccountsListReqCloudProviderEnum.Azure) { + return 'Subscriptions'; + } else if (!isNonCloudNode(provider.name ?? '')) { + return 'Accounts'; + } +} + const CardCountSection = ({ provider }: { provider: ModelPostureProvider }) => { const textStyle = 'text-p7a leading-6 text-text-text-and-icon min-w-[120px]'; const countStyle = 'text-h3 text-text-input-value'; return (
- - {!isNonCloudProvider(provider.name ?? '') ? ( - 'Active Accounts' - ) : ( - <> - {isLinuxProvider(provider.name ?? '') && 'Active hosts'} - {isKubernetesProvider(provider.name ?? '') && 'Active clusters'} - - )} - + Active {getAccountProductName(provider)} {abbreviateNumber(provider.node_count ?? 0)}
- - {!isNonCloudProvider(provider.name ?? '') ? ( - 'Inactive Accounts' - ) : ( - <> - {isLinuxProvider(provider.name ?? '') && 'Inactive hosts'} - {isKubernetesProvider(provider.name ?? '') && 'Inactive clusters'} - - )} - + Inactive {getAccountProductName(provider)} {abbreviateNumber(provider.node_count_inactive ?? 0)}
- - {!isNonCloudProvider(provider.name ?? '') ? ( - 'Scanned Accounts' - ) : ( - <> - {isLinuxProvider(provider.name ?? '') && 'Scanned hosts'} - {isKubernetesProvider(provider.name ?? '') && 'Scanned clusters'} - - )} - + Scanned {getAccountProductName(provider)} {abbreviateNumber(provider.scan_count ?? 0)}
- {!isNonCloudProvider(provider.name ?? '') ? ( + {!isNonCloudNode(provider.name ?? '') ? (
Resources @@ -240,7 +228,7 @@ const PostureCloudList = () => { return ( <> {providers - ?.filter((provider) => !isNonCloudProvider(provider.name ?? '')) + ?.filter((provider) => !isNonCloudNode(provider.name ?? '')) .map((provider) => { return ; })} @@ -259,7 +247,7 @@ const PosturenNonCloudList = () => { return ( <> {providers - ?.filter((provider) => isNonCloudProvider(provider.name ?? '')) + ?.filter((provider) => isNonCloudNode(provider.name ?? '')) .map((provider) => { return ; })} diff --git a/deepfence_frontend/apps/dashboard/src/features/postures/pages/PostureCloudDetailModal.tsx b/deepfence_frontend/apps/dashboard/src/features/postures/pages/PostureCloudDetailModal.tsx index 0e9dba842f..ad4a688a69 100644 --- a/deepfence_frontend/apps/dashboard/src/features/postures/pages/PostureCloudDetailModal.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/postures/pages/PostureCloudDetailModal.tsx @@ -11,6 +11,7 @@ import { SlidingModalHeader, } from 'ui-components'; +import { ModelCloudNodeAccountsListReqCloudProviderEnum } from '@/api/generated'; import { useCopyToClipboardState } from '@/components/CopyToClipboard'; import { CheckIcon } from '@/components/icons/common/Check'; import { CopyLineIcon } from '@/components/icons/common/CopyLine'; @@ -182,32 +183,45 @@ const DetailsComponent = ({ ); } - const keyValues = getFieldsKeyValue(cloudPosture ?? {}, { - hiddenFields: [ - 'status', - 'description', - 'node_name', - 'severity', - 'type', - 'count', - 'node_id', - 'resources', - ], - priorityFields: [ - 'cloud_provider', - 'region', - 'account_id', - 'compliance_check_type', - 'control_id', - 'group', - 'title', - 'service', - 'reason', - 'resource', - 'masked', - 'updated_at', - ], - }); + const keyValues = getFieldsKeyValue( + { + ...(cloudPosture ?? {}), + subscription_id: cloudPosture.account_id, + }, + { + hiddenFields: [ + 'status', + 'description', + 'node_name', + 'severity', + 'type', + 'count', + 'node_id', + 'resources', + cloudPosture.cloud_provider === + ModelCloudNodeAccountsListReqCloudProviderEnum.Azure + ? 'account_id' + : 'subscription_id', + ], + priorityFields: [ + 'cloud_provider', + 'region', + cloudPosture.cloud_provider === + ModelCloudNodeAccountsListReqCloudProviderEnum.Azure + ? 'subscription_id' + : 'account_id', + 'compliance_check_type', + 'control_id', + 'group', + 'title', + 'service', + 'reason', + 'resource', + 'masked', + 'updated_at', + ], + }, + ); return (
diff --git a/deepfence_frontend/apps/dashboard/src/features/postures/pages/PostureCloudScanResults.tsx b/deepfence_frontend/apps/dashboard/src/features/postures/pages/PostureCloudScanResults.tsx index 5d517919f7..30f9ddca88 100644 --- a/deepfence_frontend/apps/dashboard/src/features/postures/pages/PostureCloudScanResults.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/postures/pages/PostureCloudScanResults.tsx @@ -82,11 +82,7 @@ import { PostureScanResultsPieChart } from '@/features/postures/components/scan- import { PosturesCloudCompare } from '@/features/postures/components/scan-result/PosturesCloudCompare'; import { SearchableControl } from '@/features/postures/components/scan-result/SearchableControl'; import { providersToNameMapping } from '@/features/postures/pages/Posture'; -import { SuccessModalContent } from '@/features/settings/components/SuccessModalContent'; -import { invalidateAllQueries, queries } from '@/queries'; -import { useTheme } from '@/theme/ThemeContext'; import { - ComplianceScanNodeTypeEnum, isAlarmStatus, isDeleteStatus, isInfoStatus, @@ -95,6 +91,12 @@ import { isPassStatus, isSkipStatus, isWarnStatus, +} from '@/features/postures/utils'; +import { SuccessModalContent } from '@/features/settings/components/SuccessModalContent'; +import { invalidateAllQueries, queries } from '@/queries'; +import { useTheme } from '@/theme/ThemeContext'; +import { + ComplianceScanNodeTypeEnum, PostureSeverityType, ScanTypeEnum, } from '@/types/common'; diff --git a/deepfence_frontend/apps/dashboard/src/features/postures/pages/PostureScanResults.tsx b/deepfence_frontend/apps/dashboard/src/features/postures/pages/PostureScanResults.tsx index fa83d34331..395d46d9af 100644 --- a/deepfence_frontend/apps/dashboard/src/features/postures/pages/PostureScanResults.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/postures/pages/PostureScanResults.tsx @@ -83,11 +83,7 @@ import { PostureScanResultsPieChart } from '@/features/postures/components/scan- import { PosturesCompare } from '@/features/postures/components/scan-result/PosturesCompare'; import { SearchablePostureTestNumber } from '@/features/postures/components/scan-result/SearchableTestNumber'; import { providersToNameMapping } from '@/features/postures/pages/Posture'; -import { SuccessModalContent } from '@/features/settings/components/SuccessModalContent'; -import { invalidateAllQueries, queries } from '@/queries'; -import { useTheme } from '@/theme/ThemeContext'; import { - ComplianceScanNodeTypeEnum, isAlarmStatus, isDeleteStatus, isInfoStatus, @@ -96,6 +92,12 @@ import { isPassStatus, isSkipStatus, isWarnStatus, +} from '@/features/postures/utils'; +import { SuccessModalContent } from '@/features/settings/components/SuccessModalContent'; +import { invalidateAllQueries, queries } from '@/queries'; +import { useTheme } from '@/theme/ThemeContext'; +import { + ComplianceScanNodeTypeEnum, PostureSeverityType, ScanTypeEnum, } from '@/types/common'; diff --git a/deepfence_frontend/apps/dashboard/src/features/postures/utils/index.ts b/deepfence_frontend/apps/dashboard/src/features/postures/utils/index.ts new file mode 100644 index 0000000000..6563666eaa --- /dev/null +++ b/deepfence_frontend/apps/dashboard/src/features/postures/utils/index.ts @@ -0,0 +1,133 @@ +import { + ModelCloudComplianceStatusEnum, + ModelCloudNodeAccountsListReqCloudProviderEnum, + ModelComplianceStatusEnum, +} from '@/api/generated'; + +export const isCloudNonOrgNode = (nodeType?: string) => { + return ( + nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.Aws || + nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.Azure || + nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.Gcp + ); +}; + +export const isCloudOrgNode = (nodeType?: string) => + nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.AwsOrg || + nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.GcpOrg || + nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.AzureOrg; + +export const isNonCloudNode = (nodeType: string) => { + return ( + nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.Linux || + nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.Kubernetes + ); +}; + +export const isLinuxNodeType = (nodeType: string) => + nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.Linux; + +export const isKubernetesNodeType = (nodeType: string) => + nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.Kubernetes; + +export const isAlarmStatus = (status: string) => { + return status?.toLowerCase() === ModelCloudComplianceStatusEnum.Alarm; +}; +export const isInfoStatus = (status: string) => { + return status?.toLowerCase() === ModelCloudComplianceStatusEnum.Info; +}; +export const isOkStatus = (status: string) => { + return status?.toLowerCase() === ModelCloudComplianceStatusEnum.Ok; +}; +export const isSkipStatus = (status: string) => { + return status?.toLowerCase() === ModelCloudComplianceStatusEnum.Skip; +}; +export const isPassStatus = (status: string) => { + return status?.toLowerCase() === ModelComplianceStatusEnum.Pass; +}; +export const isWarnStatus = (status: string) => { + return status?.toLowerCase() === ModelComplianceStatusEnum.Warn; +}; +export const isNoteStatus = (status: string) => { + return status?.toLowerCase() === ModelComplianceStatusEnum.Note; +}; +export const isDeleteStatus = (status: string) => { + return ( + status?.toLowerCase() === ModelCloudComplianceStatusEnum.Delete || + status?.toLowerCase() === '' + ); +}; + +export function getDisplayNameOfNodeType( + nodeType?: ModelCloudNodeAccountsListReqCloudProviderEnum, +) { + switch (nodeType) { + case ModelCloudNodeAccountsListReqCloudProviderEnum.Azure: + return 'Subscription'; + case ModelCloudNodeAccountsListReqCloudProviderEnum.AzureOrg: + return 'Tenant'; + case ModelCloudNodeAccountsListReqCloudProviderEnum.Aws: + case ModelCloudNodeAccountsListReqCloudProviderEnum.Gcp: + case ModelCloudNodeAccountsListReqCloudProviderEnum.Linux: + case ModelCloudNodeAccountsListReqCloudProviderEnum.Kubernetes: + case ModelCloudNodeAccountsListReqCloudProviderEnum.AwsOrg: + case ModelCloudNodeAccountsListReqCloudProviderEnum.GcpOrg: + return 'Account'; + case undefined: + throw new Error(`Node type cannot be empty for display name`); + default: + // eslint-disable-next-line no-case-declarations + const _exhaustiveCheck: never = nodeType; + throw new Error(`Unhandled case: ${_exhaustiveCheck}`); + } +} + +export function getSearchableCloudAccountDisplayName( + nodeType?: ModelCloudNodeAccountsListReqCloudProviderEnum, +) { + switch (nodeType) { + case ModelCloudNodeAccountsListReqCloudProviderEnum.Azure: + return 'Subscription'; + case ModelCloudNodeAccountsListReqCloudProviderEnum.AzureOrg: + return 'Tenant'; + case ModelCloudNodeAccountsListReqCloudProviderEnum.Aws: + case ModelCloudNodeAccountsListReqCloudProviderEnum.Gcp: + case ModelCloudNodeAccountsListReqCloudProviderEnum.Linux: + case ModelCloudNodeAccountsListReqCloudProviderEnum.Kubernetes: + return 'Account'; + case ModelCloudNodeAccountsListReqCloudProviderEnum.AwsOrg: + case ModelCloudNodeAccountsListReqCloudProviderEnum.GcpOrg: + return 'Organization account'; + case undefined: + throw new Error(`Node type cannot be empty for display name`); + default: + // eslint-disable-next-line no-case-declarations + const _exhaustiveCheck: never = nodeType; + throw new Error(`Unhandled case: ${_exhaustiveCheck}`); + } +} + +export function getDeleteConfirmationDisplayName( + nodeType?: ModelCloudNodeAccountsListReqCloudProviderEnum, +) { + switch (nodeType) { + case ModelCloudNodeAccountsListReqCloudProviderEnum.Azure: + return 'The Selected subscription, resources and scans related to the subscription will be deleted.'; + case ModelCloudNodeAccountsListReqCloudProviderEnum.AzureOrg: + return 'The Selected tenant, child subscriptions related to tenant, resources and scans related to tenant will be deleted.'; + case ModelCloudNodeAccountsListReqCloudProviderEnum.Aws: + case ModelCloudNodeAccountsListReqCloudProviderEnum.Gcp: + case ModelCloudNodeAccountsListReqCloudProviderEnum.Linux: + case ModelCloudNodeAccountsListReqCloudProviderEnum.Kubernetes: + return 'The Selected cloud account, resources and scans related to the account will be deleted.'; + case ModelCloudNodeAccountsListReqCloudProviderEnum.AwsOrg: + case ModelCloudNodeAccountsListReqCloudProviderEnum.GcpOrg: + return 'The Selected org cloud account, child accounts related to org account, resources and scans related to the cloud accounts will be deleted.'; + case undefined: + throw new Error(`Node type cannot be empty for display name`); + default: + // eslint-disable-next-line no-case-declarations + const _exhaustiveCheck: never = nodeType; + throw new Error(`Unhandled case: ${_exhaustiveCheck}`); + } +} diff --git a/deepfence_frontend/apps/dashboard/src/queries/onboard.ts b/deepfence_frontend/apps/dashboard/src/queries/onboard.ts index 39446a1447..6c386e5c4d 100644 --- a/deepfence_frontend/apps/dashboard/src/queries/onboard.ts +++ b/deepfence_frontend/apps/dashboard/src/queries/onboard.ts @@ -140,6 +140,16 @@ export const onboardQueries = createQueryKeys('onboard', { }, }); + const azureOrgResultsPromise = listCloudNodeAccountApi({ + modelCloudNodeAccountsListReq: { + cloud_provider: 'azure_org', + window: { + offset: 0, + size: 1000000, + }, + }, + }); + const searchHostsApi = apiWrapper({ fn: getSearchApiClient().searchHosts, }); @@ -203,6 +213,7 @@ export const onboardQueries = createQueryKeys('onboard', { azureResults, awsOrgResults, gcpOrgResults, + azureOrgResults, ] = await Promise.all([ awsResultsPromise, hostsResultsPromise, @@ -212,6 +223,7 @@ export const onboardQueries = createQueryKeys('onboard', { azureResultsPromise, awsOrgResultsPromise, gcpOrgResultsPromise, + azureOrgResultsPromise, ]); if ( @@ -222,7 +234,8 @@ export const onboardQueries = createQueryKeys('onboard', { !gcpResults.ok || !azureResults.ok || !awsOrgResults.ok || - !gcpOrgResults.ok + !gcpOrgResults.ok || + !azureOrgResults.ok ) { // TODO(manan) handle error cases return []; @@ -328,7 +341,7 @@ export const onboardQueries = createQueryKeys('onboard', { count: azureResults.value.total, connections: ( azureResults.value.cloud_node_accounts_info?.map((result) => ({ - id: `gcp-${result.node_id}`, + id: `azure-${result.node_id}`, urlId: result.node_id ?? '', accountType: 'Azure', urlType: 'azure', @@ -342,6 +355,29 @@ export const onboardQueries = createQueryKeys('onboard', { }); } + if (azureOrgResults.value.total) { + data.push({ + id: 'azure_org', + urlId: 'azure_org', + urlType: 'azure_org', + accountType: 'Azure Organizations', + count: azureOrgResults.value.total, + connections: ( + azureOrgResults.value.cloud_node_accounts_info?.map((result) => ({ + id: `azure_org-${result.node_id}`, + urlId: result.node_id ?? '', + accountType: 'Azure Organizations', + urlType: 'azure_org', + connectionMethod: 'Cloud connector', + accountId: result.node_name ?? '-', + active: !!result.active, + })) ?? [] + ).sort((a, b) => { + return (a.accountId ?? '').localeCompare(b.accountId ?? ''); + }), + }); + } + if (hostsResults.value.length) { data.push({ id: 'hosts', diff --git a/deepfence_frontend/apps/dashboard/src/types/common.ts b/deepfence_frontend/apps/dashboard/src/types/common.ts index 5a4b4ad812..bd68afd113 100644 --- a/deepfence_frontend/apps/dashboard/src/types/common.ts +++ b/deepfence_frontend/apps/dashboard/src/types/common.ts @@ -1,5 +1,6 @@ import { ModelCloudComplianceStatusEnum, + ModelCloudNodeAccountsListReqCloudProviderEnum, ModelComplianceStatusEnum, ModelMalwareFileSeverityEnum, ModelScanResultsActionRequestScanTypeEnum, @@ -41,11 +42,21 @@ export enum ComplianceScanNodeTypeEnum { aws_org = 'aws_org', gcp = 'gcp', gcp_org = 'gcp_org', + azure_org = 'azure_org', azure = 'azure', host = 'host', kubernetes_cluster = 'kubernetes_cluster', } +type PostureEnum = + (typeof ModelCloudNodeAccountsListReqCloudProviderEnum)[keyof typeof ModelCloudNodeAccountsListReqCloudProviderEnum]; + +export type CloudNodeType = Exclude; +export type CloudNodeNonOrgType = Exclude< + PostureEnum, + 'aws_org' | 'gcp_org' | 'azure_org' | 'linux' | 'kubernetes' +>; + export const RegistryType = { azure_container_registry: 'azure_container_registry', docker_hub: 'docker_hub', @@ -69,12 +80,6 @@ export const registryTypeToNameMapping: { [key: string]: string } = { quay: 'Quay', } as const; -export type CloudNodeType = 'aws' | 'azure' | 'gcp'; -export const isCloudNode = (nodeType?: string) => - nodeType === 'aws' || nodeType === 'azure' || nodeType === 'gcp'; -export const isCloudOrgNode = (nodeType?: string) => - nodeType === 'aws_org' || nodeType === 'gcp_org'; - export type GenerativeAIIntegrationType = 'openai' | 'amazon-bedrock'; export const isCriticalSeverity = (severity: string) => { @@ -94,30 +99,3 @@ export const isUnknownSeverity = (severity: string) => { severity?.toLowerCase() === SeverityEnum.Unknown || severity?.toLowerCase() === '' ); }; -export const isAlarmStatus = (status: string) => { - return status?.toLowerCase() === ModelCloudComplianceStatusEnum.Alarm; -}; -export const isInfoStatus = (status: string) => { - return status?.toLowerCase() === ModelCloudComplianceStatusEnum.Info; -}; -export const isOkStatus = (status: string) => { - return status?.toLowerCase() === ModelCloudComplianceStatusEnum.Ok; -}; -export const isSkipStatus = (status: string) => { - return status?.toLowerCase() === ModelCloudComplianceStatusEnum.Skip; -}; -export const isPassStatus = (status: string) => { - return status?.toLowerCase() === ModelComplianceStatusEnum.Pass; -}; -export const isWarnStatus = (status: string) => { - return status?.toLowerCase() === ModelComplianceStatusEnum.Warn; -}; -export const isNoteStatus = (status: string) => { - return status?.toLowerCase() === ModelComplianceStatusEnum.Note; -}; -export const isDeleteStatus = (status: string) => { - return ( - status?.toLowerCase() === ModelCloudComplianceStatusEnum.Delete || - status?.toLowerCase() === '' - ); -}; From d1fdf92ad57b5c9cf3b6f7faa7dfc467e33b330c Mon Sep 17 00:00:00 2001 From: milan-deepfence Date: Wed, 19 Jun 2024 18:14:19 +0530 Subject: [PATCH 2/5] update missing filters for azure related changes --- .../clouds-connector/AzureConnectorForm.tsx | 3 +- .../src/features/postures/utils/index.ts | 88 +++++++------------ .../settings/pages/GlobalSettings.tsx | 15 ++-- .../threat-graph/pages/ThreatGraph.tsx | 3 +- .../tables/CloudResourcesTable.tsx | 30 ++++--- 5 files changed, 61 insertions(+), 78 deletions(-) diff --git a/deepfence_frontend/apps/dashboard/src/components/clouds-connector/AzureConnectorForm.tsx b/deepfence_frontend/apps/dashboard/src/components/clouds-connector/AzureConnectorForm.tsx index 38bc022f1b..62bd72dd00 100644 --- a/deepfence_frontend/apps/dashboard/src/components/clouds-connector/AzureConnectorForm.tsx +++ b/deepfence_frontend/apps/dashboard/src/components/clouds-connector/AzureConnectorForm.tsx @@ -20,8 +20,7 @@ export const AzureConnectorForm = () => { title="Terraform" >
- Connect to your Azure Cloud Account via Terraform. Find out more information - by{' '} + Connect to your Microsoft Azure via terraform. Find out more information by{' '} { export function getDisplayNameOfNodeType( nodeType?: ModelCloudNodeAccountsListReqCloudProviderEnum, ) { - switch (nodeType) { - case ModelCloudNodeAccountsListReqCloudProviderEnum.Azure: - return 'Subscription'; - case ModelCloudNodeAccountsListReqCloudProviderEnum.AzureOrg: - return 'Tenant'; - case ModelCloudNodeAccountsListReqCloudProviderEnum.Aws: - case ModelCloudNodeAccountsListReqCloudProviderEnum.Gcp: - case ModelCloudNodeAccountsListReqCloudProviderEnum.Linux: - case ModelCloudNodeAccountsListReqCloudProviderEnum.Kubernetes: - case ModelCloudNodeAccountsListReqCloudProviderEnum.AwsOrg: - case ModelCloudNodeAccountsListReqCloudProviderEnum.GcpOrg: - return 'Account'; - case undefined: - throw new Error(`Node type cannot be empty for display name`); - default: - // eslint-disable-next-line no-case-declarations - const _exhaustiveCheck: never = nodeType; - throw new Error(`Unhandled case: ${_exhaustiveCheck}`); + if (!nodeType) { + throw new Error(`Node type cannot be empty for display name`); + } + + if (nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.Azure) { + return 'Subscription'; + } else if (nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.AzureOrg) { + return 'Tenant'; + } else { + return 'Account'; } } export function getSearchableCloudAccountDisplayName( nodeType?: ModelCloudNodeAccountsListReqCloudProviderEnum, ) { - switch (nodeType) { - case ModelCloudNodeAccountsListReqCloudProviderEnum.Azure: - return 'Subscription'; - case ModelCloudNodeAccountsListReqCloudProviderEnum.AzureOrg: - return 'Tenant'; - case ModelCloudNodeAccountsListReqCloudProviderEnum.Aws: - case ModelCloudNodeAccountsListReqCloudProviderEnum.Gcp: - case ModelCloudNodeAccountsListReqCloudProviderEnum.Linux: - case ModelCloudNodeAccountsListReqCloudProviderEnum.Kubernetes: - return 'Account'; - case ModelCloudNodeAccountsListReqCloudProviderEnum.AwsOrg: - case ModelCloudNodeAccountsListReqCloudProviderEnum.GcpOrg: - return 'Organization account'; - case undefined: - throw new Error(`Node type cannot be empty for display name`); - default: - // eslint-disable-next-line no-case-declarations - const _exhaustiveCheck: never = nodeType; - throw new Error(`Unhandled case: ${_exhaustiveCheck}`); + if (!nodeType) { + throw new Error(`Node type cannot be empty for display name`); + } + if (nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.Azure) { + return 'Subscription'; + } else if (nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.AzureOrg) { + return 'Tenant'; + } else if (isCloudOrgNode(nodeType)) { + return 'Organization account'; + } else { + return 'Account'; } } export function getDeleteConfirmationDisplayName( nodeType?: ModelCloudNodeAccountsListReqCloudProviderEnum, ) { - switch (nodeType) { - case ModelCloudNodeAccountsListReqCloudProviderEnum.Azure: - return 'The Selected subscription, resources and scans related to the subscription will be deleted.'; - case ModelCloudNodeAccountsListReqCloudProviderEnum.AzureOrg: - return 'The Selected tenant, child subscriptions related to tenant, resources and scans related to tenant will be deleted.'; - case ModelCloudNodeAccountsListReqCloudProviderEnum.Aws: - case ModelCloudNodeAccountsListReqCloudProviderEnum.Gcp: - case ModelCloudNodeAccountsListReqCloudProviderEnum.Linux: - case ModelCloudNodeAccountsListReqCloudProviderEnum.Kubernetes: - return 'The Selected cloud account, resources and scans related to the account will be deleted.'; - case ModelCloudNodeAccountsListReqCloudProviderEnum.AwsOrg: - case ModelCloudNodeAccountsListReqCloudProviderEnum.GcpOrg: - return 'The Selected org cloud account, child accounts related to org account, resources and scans related to the cloud accounts will be deleted.'; - case undefined: - throw new Error(`Node type cannot be empty for display name`); - default: - // eslint-disable-next-line no-case-declarations - const _exhaustiveCheck: never = nodeType; - throw new Error(`Unhandled case: ${_exhaustiveCheck}`); + if (!nodeType) { + throw new Error(`Node type cannot be empty for display name`); + } + if (nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.Azure) { + return 'The Selected subscription, resources and scans related to the subscription will be deleted.'; + } else if (nodeType === ModelCloudNodeAccountsListReqCloudProviderEnum.AzureOrg) { + return 'The Selected tenant, child subscriptions related to tenant, resources and scans related to tenant will be deleted.'; + } else if (isCloudOrgNode()) { + return 'The Selected org cloud account, child accounts related to org account, resources and scans related to the cloud accounts will be deleted.'; + } else { + return 'The Selected cloud account, resources and scans related to the account will be deleted.'; } } diff --git a/deepfence_frontend/apps/dashboard/src/features/settings/pages/GlobalSettings.tsx b/deepfence_frontend/apps/dashboard/src/features/settings/pages/GlobalSettings.tsx index 65d17f1d7b..d9ad6c992c 100644 --- a/deepfence_frontend/apps/dashboard/src/features/settings/pages/GlobalSettings.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/settings/pages/GlobalSettings.tsx @@ -17,7 +17,10 @@ import { } from 'ui-components'; import { getSettingsApiClient } from '@/api/api'; -import { ModelSettingsResponse, ModelSettingUpdateRequestKeyEnum } from '@/api/generated'; +import { + SettingSettingsResponse, + SettingSettingUpdateRequestKeyEnum, +} from '@/api/generated'; import { EllipsisIcon } from '@/components/icons/common/Ellipsis'; import { SlidingModalHeaderWrapper } from '@/features/common/SlidingModalHeaderWrapper'; import { SuccessModalContent } from '@/features/settings/components/SuccessModalContent'; @@ -47,8 +50,8 @@ const action = async ({ request }: ActionFunctionArgs): Promise>; - setting: ModelSettingsResponse; + setting: SettingSettingsResponse; }) => { const fetcher = useFetcher(); const { data, state } = fetcher; @@ -141,7 +144,7 @@ const ActionDropdown = ({ setting, trigger, }: { - setting: ModelSettingsResponse; + setting: SettingSettingsResponse; trigger: React.ReactNode; }) => { const [openEditSetting, setOpenEditSetting] = useState(false); @@ -175,7 +178,7 @@ const ActionDropdown = ({ ); }; const SettingTable = () => { - const columnHelper = createColumnHelper(); + const columnHelper = createColumnHelper(); const columns = useMemo(() => { const columns = [ diff --git a/deepfence_frontend/apps/dashboard/src/features/threat-graph/pages/ThreatGraph.tsx b/deepfence_frontend/apps/dashboard/src/features/threat-graph/pages/ThreatGraph.tsx index 2ddc6b815d..798649a90c 100644 --- a/deepfence_frontend/apps/dashboard/src/features/threat-graph/pages/ThreatGraph.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/threat-graph/pages/ThreatGraph.tsx @@ -137,7 +137,7 @@ const FILTER_SEARCHPARAMS: Record< cloud_resource_only: { label: 'Scope', possibleValues: THREAT_GRAPH_SCOPE }, aws_account_ids: { label: 'AWS account' }, gcp_account_ids: { label: 'GCP account' }, - azure_account_ids: { label: 'Azure account' }, + azure_account_ids: { label: 'Azure subscription' }, }; const getAppliedFiltersCount = (searchParams: URLSearchParams) => { @@ -257,6 +257,7 @@ const Filters = () => { /> { setSearchParams((prev) => { diff --git a/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/CloudResourcesTable.tsx b/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/CloudResourcesTable.tsx index 22691955ed..d3ddf3e2db 100644 --- a/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/CloudResourcesTable.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/topology/data-components/tables/CloudResourcesTable.tsx @@ -98,7 +98,7 @@ const FILTER_SEARCHPARAMS: Record = { serviceType: 'Service type', aws_account_ids: 'AWS account', gcp_account_ids: 'GCP account', - azure_account_ids: 'Azure account', + azure_account_ids: 'Azure subscription', }; const getAppliedFiltersCount = (searchParams: URLSearchParams) => { @@ -229,6 +229,20 @@ function Filters() { const [cloudProvidersSearchText, setCloudProvidersSearchText] = useState(''); const appliedFilterCount = getAppliedFiltersCount(searchParams); + const onFilterRemove = ({ key, value }: { key: string; value: string }) => { + return () => { + setSearchParams((prev) => { + const existingValues = prev.getAll(key); + prev.delete(key); + existingValues.forEach((existingValue) => { + if (existingValue !== value) prev.append(key, existingValue); + }); + prev.delete('page'); + return prev; + }); + }; + }; + return (
@@ -313,7 +327,7 @@ function Filters() { /> { setSearchParams((prev) => { @@ -344,17 +358,7 @@ function Filters() { return ( { - setSearchParams((prev) => { - const existingValues = prev.getAll(key); - prev.delete(key); - existingValues.forEach((existingValue) => { - if (existingValue !== value) prev.append(key, existingValue); - }); - prev.delete('page'); - return prev; - }); - }} + onRemove={onFilterRemove({ key, value })} text={`${FILTER_SEARCHPARAMS[key]}: ${value}`} /> ); From a6e1a4e0944fcf4e8a97c8551635eb9e99a3a5fd Mon Sep 17 00:00:00 2001 From: milan-deepfence Date: Wed, 19 Jun 2024 18:36:34 +0530 Subject: [PATCH 3/5] replace account by subscription in integration filter --- .../forms/SearchableCloudAccountsList.tsx | 14 ++++++++++---- .../components/report-form/AdvanceFilter.tsx | 10 ++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/deepfence_frontend/apps/dashboard/src/components/forms/SearchableCloudAccountsList.tsx b/deepfence_frontend/apps/dashboard/src/components/forms/SearchableCloudAccountsList.tsx index 9f904e0588..1d340bb0d4 100644 --- a/deepfence_frontend/apps/dashboard/src/components/forms/SearchableCloudAccountsList.tsx +++ b/deepfence_frontend/apps/dashboard/src/components/forms/SearchableCloudAccountsList.tsx @@ -3,6 +3,8 @@ import { debounce } from 'lodash-es'; import { Suspense, useEffect, useMemo, useState } from 'react'; import { CircleSpinner, Combobox, ComboboxOption } from 'ui-components'; +import { ModelCloudNodeAccountsListReqCloudProviderEnum } from '@/api/generated'; +import { getDisplayNameOfNodeType } from '@/features/postures/utils'; import { queries } from '@/queries'; import { CloudNodeType } from '@/types/common'; @@ -90,8 +92,10 @@ const SearchableCloudAccounts = ({ : cloudProvider ? displayValue ? displayValue - : `${cloudProvider} account` - : 'Cloud account' + : `${cloudProvider} ${getDisplayNameOfNodeType( + cloudProvider as ModelCloudNodeAccountsListReqCloudProviderEnum, + ).toLowerCase()}` + : 'Cloud' } multiple value={selectedAccounts} @@ -147,8 +151,10 @@ export const SearchableCloudAccountsList = (props: SearchableCloudAccountsListPr return displayValue ? displayValue : cloudProvider - ? `${cloudProvider} account` - : 'Cloud account'; + ? `${cloudProvider} ${getDisplayNameOfNodeType( + cloudProvider as ModelCloudNodeAccountsListReqCloudProviderEnum, + ).toLowerCase()}` + : `Cloud`; }} multiple onQueryChange={() => { diff --git a/deepfence_frontend/apps/dashboard/src/features/integrations/components/report-form/AdvanceFilter.tsx b/deepfence_frontend/apps/dashboard/src/features/integrations/components/report-form/AdvanceFilter.tsx index 942870f242..7639d34bce 100644 --- a/deepfence_frontend/apps/dashboard/src/features/integrations/components/report-form/AdvanceFilter.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/integrations/components/report-form/AdvanceFilter.tsx @@ -12,7 +12,11 @@ import { SearchableClusterList } from '@/components/forms/SearchableClusterList' import { SearchableContainerList } from '@/components/forms/SearchableContainerList'; import { SearchableHostList } from '@/components/forms/SearchableHostList'; import { SearchableImageList } from '@/components/forms/SearchableImageList'; -import { isCloudNonOrgNode, isCloudOrgNode } from '@/features/postures/utils'; +import { + getDisplayNameOfNodeType, + isCloudNonOrgNode, + isCloudOrgNode, +} from '@/features/postures/utils'; import { ScanTypeEnum } from '@/types/common'; const getNodeTypeByProviderName = (providerName: string): string | undefined => { @@ -83,7 +87,9 @@ export const AdvancedFilter = ({
{nodeType && isCloudNode(nodeType) && ( Date: Wed, 19 Jun 2024 19:36:39 +0530 Subject: [PATCH 4/5] update label name --- .../dashboard/src/features/threat-graph/pages/ThreatGraph.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deepfence_frontend/apps/dashboard/src/features/threat-graph/pages/ThreatGraph.tsx b/deepfence_frontend/apps/dashboard/src/features/threat-graph/pages/ThreatGraph.tsx index 798649a90c..bf5b366439 100644 --- a/deepfence_frontend/apps/dashboard/src/features/threat-graph/pages/ThreatGraph.tsx +++ b/deepfence_frontend/apps/dashboard/src/features/threat-graph/pages/ThreatGraph.tsx @@ -219,6 +219,7 @@ const Filters = () => { { setSearchParams((prev) => { @@ -238,6 +239,7 @@ const Filters = () => { /> { setSearchParams((prev) => { From 4ed837fca875d7bbc2f048b318fe1c4ff878da64 Mon Sep 17 00:00:00 2001 From: milan-deepfence Date: Thu, 20 Jun 2024 19:07:39 +0530 Subject: [PATCH 5/5] fix lint issue --- .../forms/SearchableCloudAccountsList.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/deepfence_frontend/apps/dashboard/src/components/forms/SearchableCloudAccountsList.tsx b/deepfence_frontend/apps/dashboard/src/components/forms/SearchableCloudAccountsList.tsx index 1d340bb0d4..bceb51fa59 100644 --- a/deepfence_frontend/apps/dashboard/src/components/forms/SearchableCloudAccountsList.tsx +++ b/deepfence_frontend/apps/dashboard/src/components/forms/SearchableCloudAccountsList.tsx @@ -90,12 +90,12 @@ const SearchableCloudAccounts = ({ isSelectVariantType && selectedAccounts.length > 0 ? `${selectedAccounts.length} selected` : cloudProvider - ? displayValue ? displayValue - : `${cloudProvider} ${getDisplayNameOfNodeType( - cloudProvider as ModelCloudNodeAccountsListReqCloudProviderEnum, - ).toLowerCase()}` - : 'Cloud' + ? displayValue + : `${cloudProvider} ${getDisplayNameOfNodeType( + cloudProvider as ModelCloudNodeAccountsListReqCloudProviderEnum, + ).toLowerCase()}` + : 'Cloud' } multiple value={selectedAccounts} @@ -151,10 +151,10 @@ export const SearchableCloudAccountsList = (props: SearchableCloudAccountsListPr return displayValue ? displayValue : cloudProvider - ? `${cloudProvider} ${getDisplayNameOfNodeType( - cloudProvider as ModelCloudNodeAccountsListReqCloudProviderEnum, - ).toLowerCase()}` - : `Cloud`; + ? `${cloudProvider} ${getDisplayNameOfNodeType( + cloudProvider as ModelCloudNodeAccountsListReqCloudProviderEnum, + ).toLowerCase()}` + : `Cloud`; }} multiple onQueryChange={() => {