From 4ac314cc28e4e786280ef87c09edd7db5083033c Mon Sep 17 00:00:00 2001 From: karthik Date: Fri, 26 Jan 2024 14:41:01 +0530 Subject: [PATCH] add policy report mock data for dev mode setup --- plugins/tekton/dev/index.tsx | 40 ++- .../src/__fixtures__/1-pipelinesData.ts | 333 +++++++++++++++++- .../advancedClusterSecurityData.ts | 207 +++++++++++ .../tekton/src/__fixtures__/taskRunData.ts | 16 +- .../PipelineRunList/PipelineRunList.test.tsx | 4 +- .../src/hooks/useAllWatchResources.test.ts | 4 +- .../src/hooks/usePipelineRunOutputData.ts | 8 +- .../hooks/usePipelineRunScanResults.test.ts | 8 +- plugins/tekton/src/types/output.ts | 17 +- .../tekton/src/utils/taskRun-utils.test.ts | 24 +- plugins/tekton/src/utils/taskRun-utils.ts | 87 ++--- plugins/tekton/src/utils/tekton-utils.test.ts | 4 +- 12 files changed, 669 insertions(+), 83 deletions(-) create mode 100644 plugins/tekton/src/__fixtures__/advancedClusterSecurityData.ts diff --git a/plugins/tekton/dev/index.tsx b/plugins/tekton/dev/index.tsx index 56b5e0f7378..4bd731dc3e8 100644 --- a/plugins/tekton/dev/index.tsx +++ b/plugins/tekton/dev/index.tsx @@ -13,6 +13,12 @@ import { import { TestApiProvider } from '@backstage/test-utils'; import { mockKubernetesPlrResponse } from '../src/__fixtures__/1-pipelinesData'; +import { + acsDeploymentCheck, + acsImageCheckResults, + acsImageScanResult, +} from '../src/__fixtures__/advancedClusterSecurityData'; +import { enterpriseContractResult } from '../src/__fixtures__/enterpriseContractData'; import { TektonCI, tektonPlugin } from '../src/plugin'; const mockEntity: Entity = { @@ -35,13 +41,33 @@ const mockEntity: Entity = { class MockKubernetesProxyApi implements KubernetesProxyApi { async getPodLogs(_request: any): Promise { - return new Promise(resolve => { - setTimeout(() => { - resolve({ - text: `\nstreaming logs from container: ${_request.containerName} \n...`, - }); - }, 500); - }); + const delayedResponse = (data: string, ms: number) => + new Promise(resolve => { + setTimeout(() => { + resolve({ + text: data, + }); + }, ms); + }); + + if (_request.podName.includes('ec-task')) { + return delayedResponse(JSON.stringify(enterpriseContractResult), 100); + } + + if (_request.podName.includes('image-scan-task')) { + return delayedResponse(JSON.stringify(acsImageScanResult), 200); + } + + if (_request.podName.includes('image-check-task')) { + return delayedResponse(JSON.stringify(acsImageCheckResults), 300); + } + + if (_request.podName.includes('deployment-check-task')) { + return delayedResponse(JSON.stringify(acsDeploymentCheck), 400); + } + + const response = `\nstreaming logs from container: ${_request.containerName} \n...`; + return delayedResponse(response, 500); } async getEventsByInvolvedObjectName(): Promise { diff --git a/plugins/tekton/src/__fixtures__/1-pipelinesData.ts b/plugins/tekton/src/__fixtures__/1-pipelinesData.ts index b8bcd088aa5..5599944ed4b 100644 --- a/plugins/tekton/src/__fixtures__/1-pipelinesData.ts +++ b/plugins/tekton/src/__fixtures__/1-pipelinesData.ts @@ -1,3 +1,10 @@ +import { + acsDeploymentCheckTaskRun, + acsImageCheckTaskRun, + acsImageScanTaskRun, + enterpriseContractTaskRun, +} from './taskRunData'; + export const mockKubernetesPlrResponse = { pods: [ { @@ -239,6 +246,156 @@ export const mockKubernetesPlrResponse = { qosClass: 'BestEffort', }, }, + { + metadata: { + name: 'pipelineRun-ec-task-t237ev-pod', + namespace: 'karthik', + uid: '055cc13a-bd3e-414e-9eb6-e6cb72870578', + resourceVersion: '379623', + labels: { + 'backstage.io/kubernetes-id': 'developer-portal', + 'janus-idp.io/tekton': 'developer-portal', + 'tekton.dev/pipeline': 'test-pipeline', + 'tekton.dev/pipelineRun': 'test-pipeline-three', + 'tekton.dev/pipelineTask': 'scan-task', + 'tekton.dev/task': 'scan-task', + 'tekton.dev/taskRun': 'test-pipeline-8e09zm-scan-task', + }, + }, + spec: { + containers: [ + { + name: 'step-ec-report', + }, + ], + }, + status: { + phase: 'Running', + conditions: [], + + startTime: new Date('2023-12-08T12:19:38Z'), + }, + }, + { + metadata: { + name: 'pipelineRun-ec-task-t237ev-pod', + namespace: 'karthik', + uid: '055cc13a-bd3e-414e-9eb6-e6cb72870578', + resourceVersion: '379623', + labels: { + 'backstage.io/kubernetes-id': 'developer-portal', + 'janus-idp.io/tekton': 'developer-portal', + 'tekton.dev/pipeline': 'test-pipeline', + 'tekton.dev/pipelineRun': 'test-pipeline-8e09zm', + 'tekton.dev/pipelineTask': 'sbom-task', + 'tekton.dev/task': 'sbom-task', + 'tekton.dev/taskRun': 'test-pipeline-8e09zm-sbom-task', + }, + }, + spec: { + containers: [ + { + name: 'step-ec-report', + }, + ], + }, + status: { + phase: 'Succeeded', + conditions: [], + + startTime: new Date('2023-12-08T12:19:38Z'), + }, + }, + { + metadata: { + name: 'pipelineRun-image-scan-task-t237ev-pod', + namespace: 'karthik', + uid: '055cc13a-bd3e-414e-9eb6-e6cb72870578', + resourceVersion: '379623', + labels: { + 'backstage.io/kubernetes-id': 'developer-portal', + 'janus-idp.io/tekton': 'developer-portal', + 'tekton.dev/pipeline': 'test-pipeline', + 'tekton.dev/pipelineRun': 'test-pipeline-8e09zm', + 'tekton.dev/pipelineTask': 'sbom-task', + 'tekton.dev/task': 'sbom-task', + 'tekton.dev/taskRun': 'test-pipeline-8e09zm-sbom-task', + }, + }, + spec: { + containers: [ + { + name: 'step-print-scan-results', + }, + ], + }, + status: { + phase: 'Succeeded', + conditions: [], + + startTime: new Date('2023-12-08T12:19:38Z'), + }, + }, + { + metadata: { + name: 'pipelineRun-image-check-task-t237ev-pod', + namespace: 'karthik', + uid: '055cc13a-bd3e-414e-9eb6-e6cb72870578', + resourceVersion: '379623', + labels: { + 'backstage.io/kubernetes-id': 'developer-portal', + 'janus-idp.io/tekton': 'developer-portal', + 'tekton.dev/pipeline': 'test-pipeline', + 'tekton.dev/pipelineRun': 'test-pipeline-8e09zm', + 'tekton.dev/pipelineTask': 'sbom-task', + 'tekton.dev/task': 'sbom-task', + 'tekton.dev/taskRun': 'test-pipeline-8e09zm-sbom-task', + }, + }, + spec: { + containers: [ + { + name: 'step-print-scan-results', + }, + ], + }, + status: { + phase: 'Succeeded', + conditions: [], + + startTime: new Date('2023-12-08T12:19:38Z'), + }, + }, + { + metadata: { + name: 'pipelineRun-deployment-check-task-t237ev-pod', + namespace: 'karthik', + uid: '055cc13a-bd3e-414e-9eb6-e6cb72870578', + resourceVersion: '379623', + labels: { + 'backstage.io/kubernetes-id': 'developer-portal', + 'janus-idp.io/tekton': 'developer-portal', + 'tekton.dev/pipeline': 'test-pipeline', + 'tekton.dev/pipelineRun': 'test-pipeline-8e09zm', + 'tekton.dev/pipelineTask': 'sbom-task', + 'tekton.dev/task': 'sbom-task', + 'tekton.dev/taskRun': 'test-pipeline-8e09zm-sbom-task', + }, + }, + spec: { + containers: [ + { + name: 'step-print-scan-results', + }, + ], + }, + status: { + phase: 'Succeeded', + conditions: [], + + startTime: new Date('2023-12-08T12:19:38Z'), + }, + }, ], pipelineruns: [ { @@ -281,8 +438,7 @@ export const mockKubernetesPlrResponse = { { lastTransitionTime: '2023-03-30T07:05:13Z', message: 'Tasks Completed: 3 (Failed: 0, Cancelled 0), Skipped: 0', - reason: 'Succeeded', - status: 'True', + status: 'Unknown', type: 'Succeeded', }, ], @@ -415,6 +571,65 @@ export const mockKubernetesPlrResponse = { startTime: '2023-04-11T06:48:50Z', }, startTime: '2023-04-11T05:49:05Z', + }, + }, + { + apiVersion: 'tekton.dev/v1', + kind: 'PipelineRun', + metadata: { + annotations: { + 'pipeline.openshift.io/started-by': 'kube-admin', + 'chains.tekton.dev/signed': 'false', + }, + labels: { + 'backstage.io/kubernetes-id': 'test-backstage', + 'tekton.dev/pipeline': 'pipeline-test', + 'app.kubernetes.io/instance': 'abs', + 'app.kubernetes.io/name': 'ghg', + 'operator.tekton.dev/operand-name': 'ytui', + 'pipeline.openshift.io/runtime-version': 'hjkhk', + 'pipeline.openshift.io/type': 'hhu', + 'pipeline.openshift.io/runtime': 'node', + }, + name: 'pipelinerun-with-scanner-task', + namespace: 'deb-test', + resourceVersion: '117337', + uid: '0a091bbf-3813-48d3-a6ce-fc43644a9b24', + creationTimestamp: new Date('2023-04-11T12:31:56Z'), + }, + spec: { + pipelineRef: { + name: 'pipeline-test', + }, + serviceAccountName: 'pipeline', + workspaces: [], + }, + status: { + completionTime: '2023-04-11T06:49:05Z', + conditions: [ + { + lastTransitionTime: '2023-03-30T07:05:13Z', + message: 'Tasks Completed: 3 (Failed: 0, Cancelled 0), Skipped: 0', + reason: 'Succeeded', + status: 'True', + type: 'Succeeded', + }, + ], + pipelineSpec: { + tasks: [ + { + name: 'scan-task', + params: [], + taskRef: { + kind: 'ClusterTask', + name: 'scan-task', + }, + workspaces: [], + }, + ], + workspaces: [], + startTime: '2023-04-11T06:48:50Z', + }, results: [ { name: 'SCAN_OUTPUT', @@ -422,6 +637,7 @@ export const mockKubernetesPlrResponse = { '{"vulnerabilities":{\n"critical": 13,\n"high": 29,\n"medium": 32,\n"low": 3,\n"unknown": 0},\n"unpatched_vulnerabilities": {\n"critical": 0,\n"high": 1,\n"medium": 0,\n"low":1}\n}\n', }, ], + startTime: '2023-04-11T05:49:05Z', }, }, ], @@ -617,6 +833,115 @@ export const mockKubernetesPlrResponse = { }, }, }, + { + apiVersion: 'tekton.dev/v1', + kind: 'TaskRun', + metadata: { + annotations: { + 'operator.tekton.dev/last-applied-hash': 'undefined', + 'pipeline.openshift.io/started-by': 'undefined', + 'pipeline.tekton.dev/release': 'undefined', + 'tekton.dev/displayName': 'undefined', + 'tekton.dev/pipelines.minVersion': 'undefined', + 'tekton.dev/tags': 'undefined', + }, + creationTimestamp: new Date('2023-04-11T06:48:50Z'), + generation: 1, + labels: { + 'app.kubernetes.io/managed-by': 'tekton-pipelines', + 'app.kubernetes.io/version': '0.4', + 'backstage.io/kubernetes-id': 'test-backstage', + 'operator.tekton.dev/operand-name': 'openshift-pipelines-addons', + 'operator.tekton.dev/provider-type': 'redhat', + 'tekton.dev/clusterTask': 'scan-task', + 'tekton.dev/memberOf': 'tasks', + 'tekton.dev/pipeline': 'pipeline-test', + 'tekton.dev/pipelineRun': 'pipelinerun-with-scanner-task', + 'tekton.dev/pipelineTask': 'scan-task', + 'app.kubernetes.io/instance': 'xyz', + 'app.kubernetes.io/name': 'xyz', + 'pipeline.openshift.io/runtime': 'node', + 'pipeline.openshift.io/runtime-version': 'gh', + 'pipeline.openshift.io/type': 'abc', + }, + name: 'pipeline-test-wbvtlk-scan-task', + namespace: 'deb-test', + ownerReferences: [ + { + apiVersion: 'tekton.dev/v1', + blockOwnerDeletion: true, + controller: true, + kind: 'PipelineRun', + name: 'pipelinerun-with-scanner-task', + uid: '0a091bbf-3813-48d3-a6ce-fc43644a9b24', + }, + ], + resourceVersion: '117189', + uid: 'cb08cb7d-71fc-48a7-888f-4ad14a7277b9', + }, + spec: { + params: [], + resources: [], + serviceAccountName: 'pipeline', + taskRef: { + kind: 'ClusterTask', + name: 'scan-task', + }, + timeout: '1h0m0s', + }, + status: { + completionTime: '2023-04-11T06:48:56Z', + conditions: [ + { + lastTransitionTime: '2023-04-11T06:48:56Z', + message: 'All Steps have completed executing', + reason: 'Succeeded', + status: 'True', + type: 'Succeeded', + }, + ], + podName: 'pipelineRun-ec-task-t237ev-pod', + startTime: '2023-04-11T06:48:50Z', + steps: [ + { + container: 'step-tkn', + imageID: + 'registry.redhat.io/openshift-pipelines/pipelines-cli-tkn-rhel8@sha256:c73cefdd22522b2309f02dfa9858ed9079f1d5c94a3cd850f3f96dfbeafebc64', + name: 'tkn', + terminated: { + containerID: + 'cri-o://53fbddbb25c08e97d0061a3dd79021e8d411485bbc3f18cfcffd41ae3448c0d2', + exitCode: 0, + finishedAt: '2023-04-11T06:48:56Z', + reason: 'Completed', + startedAt: '2023-04-11T06:48:56Z', + }, + }, + ], + taskSpec: { + description: + 'This task performs operations on Tekton resources using tkn', + params: [], + steps: [ + { + args: ['--help'], + env: [], + image: + 'registry.redhat.io/openshift-pipelines/pipelines-cli-tkn-rhel8@sha256:c73cefdd22522b2309f02dfa9858ed9079f1d5c94a3cd850f3f96dfbeafebc64', + name: 'tkn', + resources: {}, + script: + 'if [ "false" = "true" ] && [ -e /kubeconfig ]; then\n export KUBECONFIG=""/kubeconfig\nfi\n\neval "tkn $@"\n', + securityContext: { + runAsNonRoot: true, + runAsUser: 65532, + }, + }, + ], + workspaces: [], + }, + }, + }, { apiVersion: 'tekton.dev/v1', kind: 'TaskRun', @@ -726,5 +1051,9 @@ export const mockKubernetesPlrResponse = { }, }, }, + enterpriseContractTaskRun, + acsImageScanTaskRun, + acsImageCheckTaskRun, + acsDeploymentCheckTaskRun, ], }; diff --git a/plugins/tekton/src/__fixtures__/advancedClusterSecurityData.ts b/plugins/tekton/src/__fixtures__/advancedClusterSecurityData.ts new file mode 100644 index 00000000000..3b20b544a4d --- /dev/null +++ b/plugins/tekton/src/__fixtures__/advancedClusterSecurityData.ts @@ -0,0 +1,207 @@ +import { + ACSCheckResults, + ACSImageScanResult, +} from '@aonic-ui/pipelines/dist/esm/types/components/Output/types'; + +export const acsImageScanResult: ACSImageScanResult = { + result: { + summary: { + CRITICAL: 0, + IMPORTANT: 1, + LOW: 4, + MODERATE: 4, + 'TOTAL-COMPONENTS': 6, + 'TOTAL-VULNERABILITIES': 9, + }, + vulnerabilities: [ + { + cveId: 'CVE-2005-2945', + cveSeverity: 'LOW', + cveInfo: 'https://nvd.nist.gov/vuln/detail/CVE-2005-2945', + componentName: 'arc', + componentVersion: '3.5.0', + componentFixedVersion: '2.3.1', + }, + { + cveId: 'CVE-2005-2992', + cveSeverity: 'LOW', + cveInfo: 'https://nvd.nist.gov/vuln/detail/CVE-2005-2992', + componentName: 'arc', + componentVersion: '3.5.0', + componentFixedVersion: '1.7.1', + }, + { + cveId: 'CVE-2021-3468', + cveSeverity: 'MODERATE', + cveInfo: 'https://access.redhat.com/security/cve/CVE-2021-3468', + componentName: 'avahi-libs', + componentVersion: '0.7-20.el8.aarch64', + componentFixedVersion: '', + }, + + { + cveId: 'RHSA-2023:7029', + cveSeverity: 'MODERATE', + cveInfo: 'https://access.redhat.com/errata/RHSA-2023:7029', + componentName: 'libX11', + componentVersion: '1.6.8-5.el8.aarch64', + componentFixedVersion: '0:1.6.8-6.el8', + }, + { + cveId: 'CVE-2022-3555', + cveSeverity: 'LOW', + cveInfo: 'https://access.redhat.com/security/cve/CVE-2022-3555', + componentName: 'libX11', + componentVersion: '1.6.8-5.el8.aarch64', + componentFixedVersion: '', + }, + { + cveId: 'CVE-2022-3554', + cveSeverity: 'MODERATE', + cveInfo: 'https://access.redhat.com/security/cve/CVE-2022-3554', + componentName: 'libX11-common', + componentVersion: '1.6.8-5.el8.noarch', + componentFixedVersion: '', + }, + { + cveId: 'CVE-2023-43785', + cveSeverity: 'MODERATE', + cveInfo: 'https://access.redhat.com/security/cve/CVE-2023-43785', + componentName: 'libX11-common', + componentVersion: '1.6.8-5.el8.noarch', + componentFixedVersion: '', + }, + { + cveId: 'CVE-2019-9923', + cveSeverity: 'LOW', + cveInfo: 'https://access.redhat.com/security/cve/CVE-2019-9923', + componentName: 'tar', + componentVersion: '2:1.30-9.el8.aarch64', + componentFixedVersion: '', + }, + { + cveId: 'CVE-2023-4586', + cveSeverity: 'IMPORTANT', + cveInfo: 'https://nvd.nist.gov/vuln/detail/CVE-2023-4586', + componentName: 'netty', + componentVersion: '4.1.100.final', + componentFixedVersion: '5.0.0', + }, + ], + }, +}; + +export const acsImageCheckResults: ACSCheckResults = { + results: [ + { + metadata: { + id: 'quay.io/bsutter/quarkus-demo:v2', + additionalInfo: { + name: 'quay.io/bsutter/quarkus-demo:v2', + type: 'image', + }, + }, + summary: { + CRITICAL: 0, + HIGH: 1, + LOW: 1, + MEDIUM: 0, + TOTAL: 2, + }, + violatedPolicies: [ + { + name: 'Fixable Severity at least Important', + severity: 'HIGH', + description: + 'Alert on deployments with fixable vulnerabilities with a Severity Rating at least Important', + violation: [ + "Fixable CVE-2023-6394 (CVSS 9.1) (severity Critical) found in component 'quarkus' (version 3.5.0), resolved by version 3.6.0", + ], + remediation: + 'Use your package manager to update to a fixed version in future builds or speak with your security team to mitigate the vulnerabilities.', + failingCheck: true, + }, + { + name: 'Red Hat Package Manager in Image', + severity: 'LOW', + description: + 'Alert on deployments with components of the Red Hat/Fedora/CentOS package management system.', + violation: [ + "Image includes component 'microdnf' (version 3.8.0-2.el8.aarch64)", + "Image includes component 'rpm' (version 4.14.3-26.el8.aarch64)", + ], + remediation: + "Run `rpm -e --nodeps $(rpm -qa '*rpm*' '*dnf*' '*libsolv*' '*hawkey*' 'yum*')` in the image build for production containers.", + failingCheck: false, + }, + ], + }, + ], + summary: { + CRITICAL: 0, + HIGH: 1, + LOW: 1, + MEDIUM: 0, + TOTAL: 2, + }, +}; + +export const acsDeploymentCheck: ACSCheckResults = { + results: [ + { + metadata: { + id: '2c4150a8-b7bf-46bb-89fc-84d09b345b2f', + additionalInfo: { + name: 'nodejs-ex', + namespace: 'test-namespace', + type: 'Deployment', + }, + }, + summary: { + CRITICAL: 0, + HIGH: 0, + LOW: 0, + MEDIUM: 2, + TOTAL: 2, + }, + violatedPolicies: [ + { + name: 'No resource requests or limits specified', + severity: 'MEDIUM', + description: + 'Alert on deployments that have containers without resource requests and limits', + violation: [ + "CPU limit set to 0 cores for container 'nodejs-ex'", + "CPU request set to 0 cores for container 'nodejs-ex'", + "Memory limit set to 0 MB for container 'nodejs-ex'", + "Memory request set to 0 MB for container 'nodejs-ex'", + ], + remediation: + 'Specify the requests and limits of CPU and Memory for your deployment.', + failingCheck: true, + }, + { + name: 'Pod Service Account Token Automatically Mounted', + severity: 'MEDIUM', + description: + 'Protect pod default service account tokens from compromise by minimizing the mounting of the default service account token to only those pods whose application requires interaction with the Kubernetes API.', + violation: [ + 'Deployment mounts the service account tokens.', + "Namespace has name 'prabhu'", + "Service Account is set to 'default'", + ], + remediation: + "Add `automountServiceAccountToken: false` or a value distinct from 'default' for the `serviceAccountName` key to the deployment's Pod configuration.", + failingCheck: false, + }, + ], + }, + ], + summary: { + CRITICAL: 0, + HIGH: 0, + LOW: 0, + MEDIUM: 2, + TOTAL: 2, + }, +}; diff --git a/plugins/tekton/src/__fixtures__/taskRunData.ts b/plugins/tekton/src/__fixtures__/taskRunData.ts index 1899b567b8b..3b92bd5c32d 100644 --- a/plugins/tekton/src/__fixtures__/taskRunData.ts +++ b/plugins/tekton/src/__fixtures__/taskRunData.ts @@ -165,8 +165,10 @@ export const enterpriseContractTaskRun: TaskRunKind = { apiVersion: 'tekton.dev/v1', kind: 'TaskRun', metadata: { + name: 'ec-taskrun', labels: { - 'tekton.dev/pipelineRun': 'test-plr', + 'tekton.dev/pipelineRun': 'pipelinerun-with-scanner-task', + 'tekton.dev/pipelineTask': 'ec-task', }, annotations: { 'chains.tekton.dev/signed': 'true', @@ -207,8 +209,10 @@ export const acsImageScanTaskRun: TaskRunKind = { apiVersion: 'tekton.dev/v1', kind: 'TaskRun', metadata: { + name: 'image-scan-taskrun', labels: { - 'tekton.dev/pipelineRun': 'test-plr', + 'tekton.dev/pipelineRun': 'pipelinerun-with-scanner-task', + 'tekton.dev/pipelineTask': 'image-scan-task', }, annotations: { 'chains.tekton.dev/signed': 'true', @@ -250,8 +254,10 @@ export const acsImageCheckTaskRun: TaskRunKind = { apiVersion: 'tekton.dev/v1', kind: 'TaskRun', metadata: { + name: 'image-check-taskrun', labels: { - 'tekton.dev/pipelineRun': 'test-plr', + 'tekton.dev/pipelineRun': 'pipelinerun-with-scanner-task', + 'tekton.dev/pipelineTask': 'image-check-task', }, annotations: { 'chains.tekton.dev/signed': 'true', @@ -293,8 +299,10 @@ export const acsDeploymentCheckTaskRun: TaskRunKind = { apiVersion: 'tekton.dev/v1', kind: 'TaskRun', metadata: { + name: 'deployment-check-taskrun', labels: { - 'tekton.dev/pipelineRun': 'test-plr', + 'tekton.dev/pipelineRun': 'pipelinerun-with-scanner-task', + 'tekton.dev/pipelineTask': 'deployment-check-task', }, annotations: { 'chains.tekton.dev/signed': 'true', diff --git a/plugins/tekton/src/components/PipelineRunList/PipelineRunList.test.tsx b/plugins/tekton/src/components/PipelineRunList/PipelineRunList.test.tsx index 8f498ab705f..c5b27cdc5fe 100644 --- a/plugins/tekton/src/components/PipelineRunList/PipelineRunList.test.tsx +++ b/plugins/tekton/src/components/PipelineRunList/PipelineRunList.test.tsx @@ -188,7 +188,7 @@ describe('PipelineRunList', () => { , ); - expect(queryByText('ruby-ex-git-xf45fo')).not.toBeNull(); + expect(queryByText('pipelinerun-with-scanner-task')).not.toBeNull(); }); it('should show empty state if no PipelineRuns matches selected status', () => { @@ -206,7 +206,7 @@ describe('PipelineRunList', () => { selectedClusterErrors: [], clusters: ['ocp'], setSelectedCluster: () => {}, - selectedStatus: computedStatus.Running, + selectedStatus: computedStatus.Cancelled, setSelectedStatus: () => {}, setIsExpanded: () => {}, }; diff --git a/plugins/tekton/src/hooks/useAllWatchResources.test.ts b/plugins/tekton/src/hooks/useAllWatchResources.test.ts index be7f8a7fb6d..c911208d7d3 100644 --- a/plugins/tekton/src/hooks/useAllWatchResources.test.ts +++ b/plugins/tekton/src/hooks/useAllWatchResources.test.ts @@ -29,7 +29,7 @@ describe('useAllWatchResources', () => { const { result } = renderHook(() => useAllWatchResources(k8sObjectsResponse, 0, watchedResources), ); - expect(result.current?.pipelineruns?.data).toHaveLength(2); + expect(result.current?.pipelineruns?.data).toHaveLength(3); expect(result.current?.taskruns).toBeUndefined(); }); @@ -61,6 +61,6 @@ describe('useAllWatchResources', () => { error: '', } as KubernetesObjects; rerender(); - expect(result.current?.pipelineruns?.data).toHaveLength(2); + expect(result.current?.pipelineruns?.data).toHaveLength(3); }); }); diff --git a/plugins/tekton/src/hooks/usePipelineRunOutputData.ts b/plugins/tekton/src/hooks/usePipelineRunOutputData.ts index 84608adb04e..93cb97158e0 100644 --- a/plugins/tekton/src/hooks/usePipelineRunOutputData.ts +++ b/plugins/tekton/src/hooks/usePipelineRunOutputData.ts @@ -105,25 +105,25 @@ export const usePipelineRunOutputData = ( }, ec: { data: ecData, - loading: ecLoading, + loading: ecLoading && !!ecPod, pod: ecPod, taskRun: ecTaskRun, }, acsImageScan: { data: acsImageScanData, - loading: loading, + loading: loading && !!acsImageScanPod, pod: acsImageScanPod, taskRun: acsImageScanTaskRun, }, acsImageCheck: { data: acsImageCheckData, - loading: acsImageCheckLoading, + loading: acsImageCheckLoading && !!acsImageCheckPod, pod: acsImageCheckPod, taskRun: acsImageCheckTaskRun, }, acsDeploymentCheck: { data: acsDeploymentCheckData, - loading: acsDeploymentCheckLoading, + loading: acsDeploymentCheckLoading && !!acsDeploymentCheckPod, pod: acsDeploymentCheckPod, taskRun: acsDeploymentCheckTaskRun, }, diff --git a/plugins/tekton/src/hooks/usePipelineRunScanResults.test.ts b/plugins/tekton/src/hooks/usePipelineRunScanResults.test.ts index 5f1dc6bf3a6..d59b710dafb 100644 --- a/plugins/tekton/src/hooks/usePipelineRunScanResults.test.ts +++ b/plugins/tekton/src/hooks/usePipelineRunScanResults.test.ts @@ -11,7 +11,7 @@ jest.mock('@backstage/core-plugin-api', () => ({ describe('usePipelineRunVulnerabilities', () => { it('should return vulnerabilities when SCAN_OUTPUT is set', () => { const { result } = renderHook(() => - usePipelineRunScanResults(mockKubernetesPlrResponse.pipelineruns[1]), + usePipelineRunScanResults(mockKubernetesPlrResponse.pipelineruns[2]), ); expect(result.current.vulnerabilities?.critical).toEqual(13); @@ -34,11 +34,11 @@ describe('usePipelineRunVulnerabilities', () => { const results0 = mockKubernetesPlrResponse.pipelineruns[0].status.pipelineResults?.[0]; const results1 = - mockKubernetesPlrResponse.pipelineruns[1].status.results?.[0]; + mockKubernetesPlrResponse.pipelineruns[2].status.results?.[0]; const plr = { - ...mockKubernetesPlrResponse.pipelineruns[1], + ...mockKubernetesPlrResponse.pipelineruns[2], status: { - ...mockKubernetesPlrResponse.pipelineruns[1].status, + ...mockKubernetesPlrResponse.pipelineruns[2].status, results: results0 && results1 ? [results0, results1] : [], }, }; diff --git a/plugins/tekton/src/types/output.ts b/plugins/tekton/src/types/output.ts index 2f2ddfd8f3d..e0dff5b9ab3 100644 --- a/plugins/tekton/src/types/output.ts +++ b/plugins/tekton/src/types/output.ts @@ -1,7 +1,4 @@ -import { - ECPolicy, - EnterpriseContractRule, -} from '@aonic-ui/pipelines/dist/esm/types/components/Output/types'; +import { ECPolicy } from '@aonic-ui/pipelines/dist/esm/types/components/Output/types'; import { V1Pod } from '@kubernetes/client-node'; import { ComputedStatus, TaskRunKind } from '@janus-idp/shared-react'; @@ -22,6 +19,18 @@ export type EnterpriseContractPolicy = { solution?: string; }; +export type EnterpriseContractRule = { + metadata?: { + title: string; + description: string; + collections: string[]; + code: string; + effective_on?: string; + solution?: string; + }; + msg: string; +}; + export type ComponentEnterpriseContractResult = { name: string; success: boolean; diff --git a/plugins/tekton/src/utils/taskRun-utils.test.ts b/plugins/tekton/src/utils/taskRun-utils.test.ts index bdc2d6d190d..1f83d65f746 100644 --- a/plugins/tekton/src/utils/taskRun-utils.test.ts +++ b/plugins/tekton/src/utils/taskRun-utils.test.ts @@ -44,7 +44,7 @@ describe('taskRun-utils', () => { getSortedTaskRuns(mockKubernetesPlrResponse.taskruns), '', ); - expect(activeTaskRun).toBe('pipeline-test-wbvtlk-tkn'); + expect(activeTaskRun).toBe('ec-taskrun'); }); it('should return active taskrun when active task is present', () => { @@ -122,11 +122,10 @@ describe('taskRun-utils', () => { }); it('should return the taskrun group', () => { - const outputGroup = getTaskrunsOutputGroup('test-plr', [ - acsImageScanTaskRun, - acsImageCheckTaskRun, - acsDeploymentCheckTaskRun, - ]); + const outputGroup = getTaskrunsOutputGroup( + 'pipelinerun-with-scanner-task', + [acsImageScanTaskRun, acsImageCheckTaskRun, acsDeploymentCheckTaskRun], + ); expect(outputGroup.acsImageScanTaskRun).toBeDefined(); expect(outputGroup.acsImageCheckTaskRun).toBeDefined(); @@ -136,9 +135,10 @@ describe('taskRun-utils', () => { }); it('should return the pods group', () => { - const outputGroup = getTaskrunsOutputGroup('test-plr', [ - acsImageScanTaskRun, - ]); + const outputGroup = getTaskrunsOutputGroup( + 'pipelinerun-with-scanner-task', + [acsImageScanTaskRun], + ); const podGroup = getPodsOutputGroup(outputGroup, testPipelineRunPods.pods); expect(podGroup.acsImageScanPod).toBeDefined(); @@ -156,11 +156,11 @@ describe('taskRun-utils', () => { }); it('should throw error if the json is not parsable', () => { - const errorFunction = jest.fn(); - jest.spyOn(console, 'error').mockImplementation(errorFunction); + const warnFunction = jest.fn(); + jest.spyOn(console, 'warn').mockImplementation(warnFunction); expect(formatData('application/json', 'key:value')).toEqual(''); - expect(errorFunction).toHaveBeenCalled(); + expect(warnFunction).toHaveBeenCalled(); }); it('should process the enterprise contract results and return in expected structure', () => { diff --git a/plugins/tekton/src/utils/taskRun-utils.ts b/plugins/tekton/src/utils/taskRun-utils.ts index 7d644ab6949..b1421a8ea78 100644 --- a/plugins/tekton/src/utils/taskRun-utils.ts +++ b/plugins/tekton/src/utils/taskRun-utils.ts @@ -15,6 +15,7 @@ import { ENTERPRISE_CONTRACT_POLICY_STATUS, EnterpriseContractPolicy, EnterpriseContractResult, + EnterpriseContractRule, OutputPodGroup, OutputTaskRunGroup, } from '../types/output'; @@ -160,7 +161,7 @@ export const formatData = (format: string, data: string) => { return JSON.parse(d); } catch (e) { // eslint-disable-next-line no-console - console.error('error parsing data', e); + console.warn('error parsing data', e); return ''; } }; @@ -188,43 +189,49 @@ export const mapEnterpriseContractResultData = ( }) : []; - return components?.reduce((acc: any[], compResult: any) => { - compResult?.violations?.forEach((v: any) => { - const rule: EnterpriseContractPolicy = { - title: v.metadata?.title ?? '', - description: v.metadata?.description ?? '', - status: ENTERPRISE_CONTRACT_POLICY_STATUS.failed, - timestamp: v.metadata?.effective_on, - component: compResult.name, - msg: v.msg, - collection: v.metadata?.collections, - solution: v.metadata?.solution, - }; - acc.push(rule); - }); - compResult?.warnings?.forEach((v: any) => { - const rule: EnterpriseContractPolicy = { - title: v.metadata?.title ?? '', - description: v.metadata?.description ?? '', - status: ENTERPRISE_CONTRACT_POLICY_STATUS.warnings, - timestamp: v.metadata?.effective_on, - component: compResult.name, - msg: v.msg, - collection: v.metadata?.collections, - }; - acc.push(rule); - }); - compResult?.successes?.forEach((v: any) => { - const rule: EnterpriseContractPolicy = { - title: v.metadata?.title ?? '', - description: v.metadata?.description ?? '', - status: ENTERPRISE_CONTRACT_POLICY_STATUS.successes, - component: compResult.name, - collection: v.metadata?.collections, - }; - acc.push(rule); - }); - - return acc; - }, []) as EnterpriseContractPolicy[]; + return components?.reduce( + ( + acc: EnterpriseContractPolicy[], + compResult: ComponentEnterpriseContractResult, + ) => { + compResult?.violations?.forEach((v: EnterpriseContractRule) => { + const rule: EnterpriseContractPolicy = { + title: v.metadata?.title ?? '', + description: v.metadata?.description ?? '', + status: ENTERPRISE_CONTRACT_POLICY_STATUS.failed, + timestamp: v.metadata?.effective_on, + component: compResult.name, + msg: v.msg, + collection: v.metadata?.collections, + solution: v.metadata?.solution, + }; + acc.push(rule); + }); + compResult?.warnings?.forEach((w: EnterpriseContractRule) => { + const rule: EnterpriseContractPolicy = { + title: w.metadata?.title ?? '', + description: w.metadata?.description ?? '', + status: ENTERPRISE_CONTRACT_POLICY_STATUS.warnings, + timestamp: w.metadata?.effective_on, + component: compResult.name, + msg: w.msg, + collection: w.metadata?.collections, + }; + acc.push(rule); + }); + compResult?.successes?.forEach((s: EnterpriseContractRule) => { + const rule: EnterpriseContractPolicy = { + title: s.metadata?.title ?? '', + description: s.metadata?.description ?? '', + status: ENTERPRISE_CONTRACT_POLICY_STATUS.successes, + component: compResult.name, + collection: s.metadata?.collections, + }; + acc.push(rule); + }); + + return acc; + }, + [], + ) as EnterpriseContractPolicy[]; }; diff --git a/plugins/tekton/src/utils/tekton-utils.test.ts b/plugins/tekton/src/utils/tekton-utils.test.ts index 522eecd7871..73b58f0ab48 100644 --- a/plugins/tekton/src/utils/tekton-utils.test.ts +++ b/plugins/tekton/src/utils/tekton-utils.test.ts @@ -193,9 +193,9 @@ describe('tekton-utils', () => { it('should return expect duration as - for PipelineRun without end time', () => { const mockPipelineRun: PipelineRunKind = { - ...mockKubernetesPlrResponse.pipelineruns[0], + ...mockKubernetesPlrResponse.pipelineruns[1], status: { - ...mockKubernetesPlrResponse.pipelineruns[0].status, + ...mockKubernetesPlrResponse.pipelineruns[1].status, completionTime: '', }, };