Skip to content

Commit

Permalink
added container image resource modal
Browse files Browse the repository at this point in the history
  • Loading branch information
milan-deepfence committed Oct 18, 2023
1 parent f28070e commit 1a80c92
Show file tree
Hide file tree
Showing 11 changed files with 328 additions and 55 deletions.
4 changes: 1 addition & 3 deletions deepfence_frontend/apps/dashboard/api-spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -10752,7 +10752,6 @@
"description": { "type": "string" },
"doc_id": { "type": "string" },
"group": { "type": "string" },
"masked": { "type": "boolean" },
"reason": { "type": "string" },
"region": { "type": "string" },
"resource": { "type": "string" },
Expand Down Expand Up @@ -10911,7 +10910,6 @@
"file_sev_score": { "type": "number" },
"file_severity": { "type": "string" },
"image_layer_id": { "type": "string" },
"masked": { "type": "boolean" },
"meta": { "type": "array", "items": { "type": "string" }, "nullable": true },
"meta_rules": { "$ref": "#/components/schemas/IngestersMetaRules" },
"rule_name": { "type": "string" },
Expand Down Expand Up @@ -11076,7 +11074,6 @@
"type": "object",
"properties": { "level": { "type": "string" }, "score": { "type": "number" } }
},
"masked": { "type": "boolean" },
"scan_id": { "type": "string" }
}
},
Expand Down Expand Up @@ -12789,6 +12786,7 @@
"type": "object",
"properties": {
"mask_across_hosts_and_images": { "type": "boolean" },
"mask_in_this_host_or_image_tags": { "type": "boolean" },
"result_ids": {
"type": "array",
"items": { "type": "string" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,6 @@ export interface IngestersCloudCompliance {
* @memberof IngestersCloudCompliance
*/
group?: string;
/**
*
* @type {boolean}
* @memberof IngestersCloudCompliance
*/
masked?: boolean;
/**
*
* @type {string}
Expand Down Expand Up @@ -163,7 +157,6 @@ export function IngestersCloudComplianceFromJSONTyped(json: any, ignoreDiscrimin
'description': !exists(json, 'description') ? undefined : json['description'],
'doc_id': !exists(json, 'doc_id') ? undefined : json['doc_id'],
'group': !exists(json, 'group') ? undefined : json['group'],
'masked': !exists(json, 'masked') ? undefined : json['masked'],
'reason': !exists(json, 'reason') ? undefined : json['reason'],
'region': !exists(json, 'region') ? undefined : json['region'],
'resource': !exists(json, 'resource') ? undefined : json['resource'],
Expand Down Expand Up @@ -194,7 +187,6 @@ export function IngestersCloudComplianceToJSON(value?: IngestersCloudCompliance
'description': value.description,
'doc_id': value.doc_id,
'group': value.group,
'masked': value.masked,
'reason': value.reason,
'region': value.region,
'resource': value.resource,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,6 @@ export interface IngestersMalware {
* @memberof IngestersMalware
*/
image_layer_id?: string;
/**
*
* @type {boolean}
* @memberof IngestersMalware
*/
masked?: boolean;
/**
*
* @type {Array<string>}
Expand Down Expand Up @@ -136,7 +130,6 @@ export function IngestersMalwareFromJSONTyped(json: any, ignoreDiscriminator: bo
'file_sev_score': !exists(json, 'file_sev_score') ? undefined : json['file_sev_score'],
'file_severity': !exists(json, 'file_severity') ? undefined : json['file_severity'],
'image_layer_id': !exists(json, 'image_layer_id') ? undefined : json['image_layer_id'],
'masked': !exists(json, 'masked') ? undefined : json['masked'],
'meta': !exists(json, 'meta') ? undefined : json['meta'],
'meta_rules': !exists(json, 'meta_rules') ? undefined : IngestersMetaRulesFromJSON(json['meta_rules']),
'rule_name': !exists(json, 'rule_name') ? undefined : json['rule_name'],
Expand All @@ -162,7 +155,6 @@ export function IngestersMalwareToJSON(value?: IngestersMalware | null): any {
'file_sev_score': value.file_sev_score,
'file_severity': value.file_severity,
'image_layer_id': value.image_layer_id,
'masked': value.masked,
'meta': value.meta,
'meta_rules': IngestersMetaRulesToJSON(value.meta_rules),
'rule_name': value.rule_name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,6 @@ export interface IngestersSecret {
* @memberof IngestersSecret
*/
Severity?: IngestersSecretSeverity;
/**
*
* @type {boolean}
* @memberof IngestersSecret
*/
masked?: boolean;
/**
*
* @type {string}
Expand Down Expand Up @@ -99,7 +93,6 @@ export function IngestersSecretFromJSONTyped(json: any, ignoreDiscriminator: boo
'Match': !exists(json, 'Match') ? undefined : IngestersSecretMatchFromJSON(json['Match']),
'Rule': !exists(json, 'Rule') ? undefined : IngestersSecretRuleFromJSON(json['Rule']),
'Severity': !exists(json, 'Severity') ? undefined : IngestersSecretSeverityFromJSON(json['Severity']),
'masked': !exists(json, 'masked') ? undefined : json['masked'],
'scan_id': !exists(json, 'scan_id') ? undefined : json['scan_id'],
};
}
Expand All @@ -117,7 +110,6 @@ export function IngestersSecretToJSON(value?: IngestersSecret | null): any {
'Match': IngestersSecretMatchToJSON(value.Match),
'Rule': IngestersSecretRuleToJSON(value.Rule),
'Severity': IngestersSecretSeverityToJSON(value.Severity),
'masked': value.masked,
'scan_id': value.scan_id,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ export interface ModelScanResultsMaskRequest {
* @memberof ModelScanResultsMaskRequest
*/
mask_across_hosts_and_images?: boolean;
/**
*
* @type {boolean}
* @memberof ModelScanResultsMaskRequest
*/
mask_in_this_host_or_image_tags?: boolean;
/**
*
* @type {Array<string>}
Expand Down Expand Up @@ -82,6 +88,7 @@ export function ModelScanResultsMaskRequestFromJSONTyped(json: any, ignoreDiscri
return {

'mask_across_hosts_and_images': !exists(json, 'mask_across_hosts_and_images') ? undefined : json['mask_across_hosts_and_images'],
'mask_in_this_host_or_image_tags': !exists(json, 'mask_in_this_host_or_image_tags') ? undefined : json['mask_in_this_host_or_image_tags'],
'result_ids': json['result_ids'],
'scan_id': json['scan_id'],
'scan_type': json['scan_type'],
Expand All @@ -98,6 +105,7 @@ export function ModelScanResultsMaskRequestToJSON(value?: ModelScanResultsMaskRe
return {

'mask_across_hosts_and_images': value.mask_across_hosts_and_images,
'mask_in_this_host_or_image_tags': value.mask_in_this_host_or_image_tags,
'result_ids': value.result_ids,
'scan_id': value.scan_id,
'scan_type': value.scan_type,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { useSuspenseQuery } from '@suspensive/react-query';
import {
SlidingModal,
SlidingModalCloseButton,
SlidingModalContent,
SlidingModalHeader,
} from 'ui-components';

import { TruncatedText } from '@/components/TruncatedText';
import {
Metadata,
toTopologyMetadataString,
} from '@/features/topology/components/node-details/Metadata';
import { queries } from '@/queries';

const useResourceDetails = ({ nodeId }: { nodeId: string }) => {
return useSuspenseQuery({
...queries.lookup.containerImage({
nodeId: nodeId,
}),
});
};
export const ResourceDetailModal = ({
nodeId,
open,
onClose,
}: {
nodeId: string;
open: boolean;
onClose: React.Dispatch<React.SetStateAction<boolean>>;
}) => {
const { data } = useResourceDetails({
nodeId,
});

return (
<SlidingModal
open={open}
onOpenChange={(state) => {
onClose(state);
}}
size="m"
>
<SlidingModalCloseButton />
<SlidingModalHeader>
<div className="p-4 text-h3 dark:text-text-text-and-icon dark:bg-bg-breadcrumb-bar ">
<div className="overflow-hidden">
<TruncatedText text="Resource details" />
</div>
</div>
</SlidingModalHeader>
<SlidingModalContent>
<div className="mx-4 mt-4">
<Metadata
title=""
data={{
node_name: toTopologyMetadataString(data?.imageData?.node_name),
docker_image_name: toTopologyMetadataString(
data?.imageData?.docker_image_name,
),
docker_image_tag: toTopologyMetadataString(
data?.imageData?.docker_image_tag,
),
docker_image_size: toTopologyMetadataString(
data?.imageData?.docker_image_size,
),
docker_image_created_at: toTopologyMetadataString(
data?.imageData?.docker_image_created_at,
),
docker_image_id: toTopologyMetadataString(data?.imageData?.docker_image_id),
}}
/>
</div>
</SlidingModalContent>
</SlidingModal>
);
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useSuspenseQuery } from '@suspensive/react-query';
import { Suspense } from 'react';
import { Suspense, useState } from 'react';
import { useParams, useSearchParams } from 'react-router-dom';
import {
Button,
Expand All @@ -19,7 +19,7 @@ import { CopyLineIcon } from '@/components/icons/common/CopyLine';
import { PopOutIcon } from '@/components/icons/common/PopOut';
import { SeverityBadge } from '@/components/SeverityBadge';
import { MalwareIcon } from '@/components/sideNavigation/icons/Malware';
import { TruncatedText } from '@/components/TruncatedText';
import { ResourceDetailModal } from '@/features/malwares/components/ResourceDetailModal';
import { queries } from '@/queries';
import { formatMilliseconds } from '@/utils/date';
import { replacebyUppercaseCharacters } from '@/utils/label';
Expand Down Expand Up @@ -134,6 +134,8 @@ const DetailsComponent = () => {
data: { data: malwares },
} = useGetMalwareDetails();

const [showResourceModal, setShowResourceModal] = useState(false);

if (!malwares.length) {
return (
<div className="flex items-center p-4 justify-center">
Expand Down Expand Up @@ -196,8 +198,32 @@ const DetailsComponent = () => {
<div className="text-p1">
{malware.resources.map((resource) => {
if (!resource.node_id || !resource.node_type) {
return null;
}
if (resource.node_type === 'container_image') {
return (
<TruncatedText key={resource.node_id} text={resource.name ?? '-'} />
<>
<Suspense fallback={<CircleSpinner size="md" />}>
{showResourceModal && (
<ResourceDetailModal
open={showResourceModal}
onClose={setShowResourceModal}
nodeId={resource.node_id}
/>
)}
</Suspense>

<button
type="button"
key={resource.node_id}
onClick={() => {
setShowResourceModal(true);
}}
className="text-p1 w-fit dark:text-accent-accent"
>
{resource.name}
</button>
</>
);
}
let redirectPath = '';
Expand All @@ -206,12 +232,6 @@ const DetailsComponent = () => {
} else if (resource.node_type === 'container') {
redirectPath = `container?containers=${resource.node_id}`;
}
if (resource.node_type === 'pod') {
redirectPath = `pod?pods=${resource.name}`;
}
if (resource.node_type === 'kubernetes_cluster') {
redirectPath = `kubernetes_cluster?clusters=${resource.node_id}`;
}
return (
<DFLink
key={resource.node_id}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { useSuspenseQuery } from '@suspensive/react-query';
import {
SlidingModal,
SlidingModalCloseButton,
SlidingModalContent,
SlidingModalHeader,
} from 'ui-components';

import { TruncatedText } from '@/components/TruncatedText';
import {
Metadata,
toTopologyMetadataString,
} from '@/features/topology/components/node-details/Metadata';
import { queries } from '@/queries';

const useResourceDetails = ({ nodeId }: { nodeId: string }) => {
return useSuspenseQuery({
...queries.lookup.containerImage({
nodeId: nodeId,
}),
});
};
export const ResourceDetailModal = ({
nodeId,
open,
onClose,
}: {
nodeId: string;
open: boolean;
onClose: React.Dispatch<React.SetStateAction<boolean>>;
}) => {
const { data } = useResourceDetails({
nodeId,
});

return (
<SlidingModal
open={open}
onOpenChange={(state) => {
onClose(state);
}}
size="m"
>
<SlidingModalCloseButton />
<SlidingModalHeader>
<div className="p-4 text-h3 dark:text-text-text-and-icon dark:bg-bg-breadcrumb-bar ">
<div className="overflow-hidden">
<TruncatedText text="Resource details" />
</div>
</div>
</SlidingModalHeader>
<SlidingModalContent>
<div className="mx-4 mt-4">
<Metadata
title=""
data={{
node_name: toTopologyMetadataString(data?.imageData?.node_name),
docker_image_name: toTopologyMetadataString(
data?.imageData?.docker_image_name,
),
docker_image_tag: toTopologyMetadataString(
data?.imageData?.docker_image_tag,
),
docker_image_size: toTopologyMetadataString(
data?.imageData?.docker_image_size,
),
docker_image_created_at: toTopologyMetadataString(
data?.imageData?.docker_image_created_at,
),
docker_image_id: toTopologyMetadataString(data?.imageData?.docker_image_id),
}}
/>
</div>
</SlidingModalContent>
</SlidingModal>
);
};
Loading

0 comments on commit 1a80c92

Please sign in to comment.