Skip to content

Commit

Permalink
fix: ec regex to extract voilation reports from tkn logs
Browse files Browse the repository at this point in the history
  • Loading branch information
sahil143 committed Jan 16, 2025
1 parent 38a7c3b commit ea092ec
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const EnterpriseContractTable: React.FC<
<Table variant="compact">
<Thead>
<Tr>
<Th width={10} />
<Th width={10} aria-label="expand toggle" />
<Th width={30} sort={getSortParams(1)}>
Rules
</Th>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,16 @@ describe('useEnterpriseContractResultFromLogs', () => {

it('should call tknResults when taskRun is empty array', () => {
mockUseTaskRuns.mockReturnValueOnce([[], true, undefined]);
mockGetTaskRunLogs.mockReturnValue(`asdfcdfadsf
[report-json] { "components": [] }
`);
mockGetTaskRunLogs.mockReturnValue(`
step-vulnerabilities :-
Lorem Ipsum some logs
step-report-json :-
{"success":true,"components":[]}
step-something-else :-
Some other logs
`);
const { result } = renderHook(() => useEnterpriseContractResultFromLogs('dummy-abcd'));
const [, loaded] = result.current;
expect(mockCommmonFetchJSON).toHaveBeenCalled();
Expand Down Expand Up @@ -109,8 +116,15 @@ describe('useEnterpriseContractResultFromLogs', () => {
undefined,
]);
mockCommmonFetchJSON.mockRejectedValue({ code: 404 });
mockGetTaskRunLogs.mockReturnValue(`asdfcdfadsf
[report-json] { "components": [] }
mockGetTaskRunLogs.mockReturnValue(`
step-vulnerabilities :-
Lorem Ipsum some logs
step-report-json :-
{"success":true,"components":[]}
step-something-else :-
Some other logs
`);

const { result, waitForNextUpdate } = renderHook(() =>
Expand Down
86 changes: 64 additions & 22 deletions src/components/EnterpriseContract/__tests__/utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,69 @@
import { extractEcResultsFromTaskRunLogs } from '../utils';

describe('extractEcResultsFromTaskRunLogs', () => {
it('should extract logs from string ', () => {
expect(
extractEcResultsFromTaskRunLogs(`asdfcdfadsf
[report-json] { "components": [] }
`),
).toEqual({ components: [] });
expect(
extractEcResultsFromTaskRunLogs(`asdfcdfadsf
[report-json] { "components":
[report-json] [] }
safkjasdfj 9034823 0dju@#$@#
`),
).toEqual({ components: [] });

expect(
extractEcResultsFromTaskRunLogs(`asdfcdfadsf
[report] { "components": [] }
[report-json] { "components":
[report-json] [] }
safkjasdfj 9034823 0dju@#$@#
`),
).toEqual({ components: [] });
test('should extract and parse JSON from logs correctly', () => {
const logs = `
step-vulnerabilities :-
Lorem Ipsum some logs
step-report-json :-
{"success":true,"components":[{"name":"component-name","details":"example"}]}
step-something-else :-
Some other logs
`;

const expectedResult = {
success: true,
components: [
{
name: 'component-name',
details: 'example',
},
],
};
expect(extractEcResultsFromTaskRunLogs(logs)).toEqual(expectedResult);
});

test('should return null if JSON parsing fails', () => {
const logs = `
step-report-json :-
{invalid JSON}
`;
expect(extractEcResultsFromTaskRunLogs(logs)).toBeNull();
});

test('should return null if step-report-json is missing', () => {
const logs = `
step-vulnerabilities :-
Lorem Ipsum some logs
`;

expect(extractEcResultsFromTaskRunLogs(logs)).toBeNull();
});

test('should handle multiple step-report-json blocks and extract the first one', () => {
const logs = `
step-report-json :-
{"success":true,"components":[{"name":"first-component","details":"example"}]}
step-report-json :-
{"success":false,"components":[{"name":"second-component","details":"example"}]}
`;

const expectedResult = {
success: true,
components: [
{
name: 'first-component',
details: 'example',
},
],
};
expect(extractEcResultsFromTaskRunLogs(logs)).toEqual(expectedResult);
});

test('should handle empty logs and return null', () => {
expect(extractEcResultsFromTaskRunLogs(``)).toBeNull();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export const useEnterpriseContractResultFromLogs = (
const [fetchTknLogs, setFetchTknLogs] = React.useState<boolean>(false);
const [ecJson, setEcJson] = React.useState<EnterpriseContractResult>();
const [ecLoaded, setEcLoaded] = React.useState<boolean>(false);
const podName = loaded && !error ? taskRun?.[0]?.status?.podName : null;
const ecResultOpts = React.useMemo(() => {
const podName = loaded && !error ? taskRun?.[0]?.status?.podName : null;
return podName
? {
ns: namespace,
Expand All @@ -34,12 +34,13 @@ export const useEnterpriseContractResultFromLogs = (
},
}
: null;
}, [loaded, error, taskRun, namespace]);
}, [podName, namespace]);

React.useEffect(() => {
let unmount = false;
if (loaded && !ecResultOpts) {
setFetchTknLogs(true);
return;
}
if (ecResultOpts) {
commonFetchJSON(getK8sResourceURL(PodModel, undefined, ecResultOpts))
Expand All @@ -66,7 +67,7 @@ export const useEnterpriseContractResultFromLogs = (

React.useEffect(() => {
let unmount = false;
if (fetchTknLogs) {
if (fetchTknLogs && !ecLoaded) {
const fetch = async () => {
try {
const pid = getPipelineRunFromTaskRunOwnerRef(taskRun[0])?.uid;
Expand Down Expand Up @@ -96,7 +97,7 @@ export const useEnterpriseContractResultFromLogs = (
return () => {
unmount = true;
};
}, [fetchTknLogs, taskRun, workspace]);
}, [ecLoaded, fetchTknLogs, taskRun, workspace]);

const ecResult = React.useMemo(() => {
// filter out components for which ec didn't execute because invalid image URL
Expand Down
24 changes: 21 additions & 3 deletions src/components/EnterpriseContract/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,26 @@ export const getRuleStatus = (type: ENTERPRISE_CONTRACT_STATUS) => {
}
};

/**
* This regex expect the logs from tekton results to be in this formay
*
* ```
* step-vulnerabilities :-
* Lorem Ipsum some logs
*
* step-report-json :-
* {"success":true,"components":[{"name":"devfile-sample-code-with-quarkus-1",<... ec report in JSON ...>,}]}
*
* ```
*
*/
const EC_REPORT_JSON_REGEX = /((?<=step-report-json\s*:-\s*)(\{.*?\})(?=\s*step-|$))/g;

export const extractEcResultsFromTaskRunLogs = (logs: string): EnterpriseContractResult => {
const extractedLogs = logs.match(/(\[report-json\] ).+/g);
const json = JSON.parse(extractedLogs.map((l) => l.replace('[report-json] ', '')).join(''));
return json;
const extractedLogs = logs.match(EC_REPORT_JSON_REGEX);
try {
return JSON.parse(extractedLogs[0]);
} catch {
return null;
}

Check warning on line 68 in src/components/EnterpriseContract/utils.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/EnterpriseContract/utils.tsx#L67-L68

Added lines #L67 - L68 were not covered by tests
};

0 comments on commit ea092ec

Please sign in to comment.