Skip to content

Commit

Permalink
feat: add support for snyk policy
Browse files Browse the repository at this point in the history
  • Loading branch information
YairZ101 committed Mar 13, 2022
1 parent 94829f0 commit b36ae33
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 35 deletions.
1 change: 1 addition & 0 deletions src/cli/commands/test/iac-local-execution/index.ts
Expand Up @@ -123,6 +123,7 @@ export async function test(
resultsWithCustomSeverities,
options,
orgPublicId,
policy,
);
}

Expand Down
11 changes: 7 additions & 4 deletions src/cli/commands/test/iac-local-execution/share-results.ts
@@ -1,12 +1,15 @@
import { isFeatureFlagSupportedForOrg } from '../../../../lib/feature-flags';
import { shareResults } from '../../../../lib/iac/cli-share-results';
import { Policy } from '../../../../lib/policy/find-and-load-policy';
import { FeatureFlagError } from './assert-iac-options-flag';
import { formatShareResults } from './share-results-formatter';
import { IacFileScanResult, IaCTestFlags } from './types';

export async function formatAndShareResults(
results,
options,
orgPublicId,
results: IacFileScanResult[],
options: IaCTestFlags,
orgPublicId: string,
policy: Policy | undefined,
): Promise<Record<string, string>> {
const isCliReportEnabled = await isFeatureFlagSupportedForOrg(
'iacCliShareResults',
Expand All @@ -18,5 +21,5 @@ export async function formatAndShareResults(

const formattedResults = formatShareResults(results, options);

return await shareResults(formattedResults);
return await shareResults(formattedResults, policy);
}
6 changes: 5 additions & 1 deletion src/lib/iac/cli-share-results.ts
Expand Up @@ -4,11 +4,15 @@ import { getAuthHeader } from '../api-token';
import { IacShareResultsFormat } from '../../cli/commands/test/iac-local-execution/types';
import { convertIacResultToScanResult } from './envelope-formatters';
import { AuthFailedError } from '../errors/authentication-failed-error';
import { Policy } from '../policy/find-and-load-policy';

export async function shareResults(
results: IacShareResultsFormat[],
policy: Policy | undefined,
): Promise<Record<string, string>> {
const scanResults = results.map(convertIacResultToScanResult);
const scanResults = results.map((result) =>
convertIacResultToScanResult(result, policy),
);

const { res, body } = await makeRequest({
method: 'POST',
Expand Down
3 changes: 3 additions & 0 deletions src/lib/iac/envelope-formatters.ts
Expand Up @@ -3,9 +3,11 @@ import {
PolicyMetadata,
} from '../../cli/commands/test/iac-local-execution/types';
import { ScanResult } from '../ecosystems/types';
import { Policy } from '../policy/find-and-load-policy';

export function convertIacResultToScanResult(
iacResult: IacShareResultsFormat,
policy: Policy | undefined,
): ScanResult {
return {
identity: {
Expand All @@ -21,5 +23,6 @@ export function convertIacResultToScanResult(
}),
name: iacResult.projectName,
target: { name: iacResult.projectName },
policy: policy?.toString() ?? '',
};
}
57 changes: 37 additions & 20 deletions test/jest/unit/iac/cli-share-results.fixtures.ts
Expand Up @@ -35,26 +35,24 @@ const anotherPolicyStub: PolicyMetadata = {
docId: 1,
};

export function generateScanResults(): IacShareResultsFormat[] {
return [
{
projectName: 'projectA',
targetFile: 'file.yaml',
filePath: '/some/path/to/file.yaml',
fileType: 'yaml',
projectType: IacProjectType.K8S,
violatedPolicies: [{ ...policyStub }, { ...anotherPolicyStub }],
},
{
projectName: 'projectB',
targetFile: 'file.yaml',
filePath: '/some/path/to/file.yaml',
fileType: 'yaml',
projectType: IacProjectType.K8S,
violatedPolicies: [{ ...policyStub }],
},
];
}
export const scanResults: IacShareResultsFormat[] = [
{
projectName: 'projectA',
targetFile: 'file.yaml',
filePath: '/some/path/to/file.yaml',
fileType: 'yaml',
projectType: IacProjectType.K8S,
violatedPolicies: [{ ...policyStub }, { ...anotherPolicyStub }],
},
{
projectName: 'projectB',
targetFile: 'file.yaml',
filePath: '/some/path/to/file.yaml',
fileType: 'yaml',
projectType: IacProjectType.K8S,
violatedPolicies: [{ ...policyStub }],
},
];

export const expectedEnvelopeFormatterResults = [
{
Expand Down Expand Up @@ -120,6 +118,7 @@ export const expectedEnvelopeFormatterResults = [
},
],
name: 'projectA',
policy: '',
target: { name: 'projectA' },
},
{
Expand Down Expand Up @@ -158,6 +157,24 @@ export const expectedEnvelopeFormatterResults = [
},
],
name: 'projectB',
policy: '',
target: { name: 'projectB' },
},
];

export const expectedEnvelopeFormatterResultsWithPolicy = expectedEnvelopeFormatterResults.map(
(result) => {
return {
...result,
policy: `# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
version: v1.22.2
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
ignore:
SNYK-CC-TF-4:
- '*':
reason: IGNORE ALL THE THINGS!
patch: {}
`,
};
},
);
43 changes: 33 additions & 10 deletions test/jest/unit/iac/cli-share-results.spec.ts
@@ -1,35 +1,35 @@
import { shareResults } from '../../../../src/lib/iac/cli-share-results';
import {
expectedEnvelopeFormatterResults,
generateScanResults,
expectedEnvelopeFormatterResultsWithPolicy,
scanResults,
} from './cli-share-results.fixtures';
import * as request from '../../../../src/lib/request';
import * as envelopeFormatters from '../../../../src/lib/iac/envelope-formatters';
import { IacShareResultsFormat } from '../../../../src/cli/commands/test/iac-local-execution/types';
import { Policy } from '../../../../src/lib/policy/find-and-load-policy';
import * as snykPolicyLib from 'snyk-policy';

describe('CLI Share Results', () => {
let scanResults: IacShareResultsFormat[];
let snykPolicy: Policy;
let requestSpy, envelopeFormattersSpy;

beforeAll(async () => {
scanResults = generateScanResults();
snykPolicy = await snykPolicyLib.load('test/jest/unit/iac/fixtures');
requestSpy = await jest.spyOn(request, 'makeRequest');
envelopeFormattersSpy = await jest.spyOn(
envelopeFormatters,
'convertIacResultToScanResult',
);
});

beforeEach(async () => {
await shareResults(scanResults);
});

afterEach(() => {
requestSpy.mockClear();
envelopeFormattersSpy.mockClear();
});

it("converts the results to Envelops's ScanResult interface", () => {
it("converts the results to Envelope's ScanResult interface - without .snyk policies", async () => {
await shareResults(scanResults, undefined);

expect(envelopeFormattersSpy.mock.calls.length).toBe(2);

const [firstCall, secondCall] = envelopeFormattersSpy.mock.calls;
Expand All @@ -44,7 +44,30 @@ describe('CLI Share Results', () => {
expect(secondCallResult.value).toEqual(expectedEnvelopeFormatterResults[1]);
});

it('forwards value to iac-cli-share-results endpoint', () => {
it("converts the results to Envelope's ScanResult interface - with .snyk policies", async () => {
await shareResults(scanResults, snykPolicy);

expect(envelopeFormattersSpy.mock.calls.length).toBe(2);

const [firstCall, secondCall] = envelopeFormattersSpy.mock.calls;
expect(firstCall[0]).toEqual(scanResults[0]);
expect(secondCall[0]).toEqual(scanResults[1]);

const [
firstCallResult,
secondCallResult,
] = envelopeFormattersSpy.mock.results;
expect(firstCallResult.value).toEqual(
expectedEnvelopeFormatterResultsWithPolicy[0],
);
expect(secondCallResult.value).toEqual(
expectedEnvelopeFormatterResultsWithPolicy[1],
);
});

it('forwards value to iac-cli-share-results endpoint', async () => {
await shareResults(scanResults, undefined);

expect(requestSpy.mock.calls.length).toBe(1);

expect(requestSpy.mock.calls[0][0]).toMatchObject({
Expand Down
8 changes: 8 additions & 0 deletions test/jest/unit/iac/fixtures/.snyk
@@ -0,0 +1,8 @@
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
version: v1.22.1
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
ignore:
SNYK-CC-TF-4:
- '*':
reason: IGNORE ALL THE THINGS!
patch: {}

0 comments on commit b36ae33

Please sign in to comment.