Skip to content

Commit

Permalink
Merge pull request #1719 from snyk/fix/file-content-in-iac-analytics
Browse files Browse the repository at this point in the history
fix: include file content in iac analytics
  • Loading branch information
rontalx authored Mar 15, 2021
2 parents 3a1c3d4 + bb63bba commit 183f676
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/cli/commands/test/iac-local-execution/file-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ export async function loadFiles(pathToScan: string): Promise<IacFileData[]> {
let filePaths = [pathToScan];

if (isLocalFolder(pathToScan)) {
filePaths = await getFilePathsFromDirectory(pathToScan);
filePaths = getFilePathsFromDirectory(pathToScan);
}

const filesToScan: IacFileData[] = [];
for (const filePath of filePaths) {
const fileData = await tryLoadFileData(filePath);
if (fileData) filesToScan.push(fileData!);
if (fileData) filesToScan.push(fileData);
}

if (filesToScan.length === 0) {
Expand Down
26 changes: 24 additions & 2 deletions src/cli/commands/test/iac-local-execution/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { parseFiles } from './file-parser';
import { scanFiles } from './file-scanner';
import { formatScanResults } from './results-formatter';
import { isLocalFolder } from '../../../../lib/detect';
import { IacOptionFlags } from './types';
import {
IacOptionFlags,
IacFileParsed,
IacFileParseFailure,
SafeAnalyticsOutput,
} from './types';
import { initLocalCache } from './local-cache';

// this method executes the local processing engine and then formats the results to adapt with the CLI output.
Expand All @@ -19,9 +24,26 @@ export async function test(pathToScan: string, options: IacOptionFlags) {

if (isLocalFolder(pathToScan)) {
// TODO: This mutation is here merely to support how the old/current directory scan printing works.
options.iacDirFiles = [...parsedFiles, ...failedFiles];
// NOTE: No file or parsed file data should leave this function.
options.iacDirFiles = [...parsedFiles, ...failedFiles].map(
removeFileContent,
);
}

// TODO: add support for proper typing of old TestResult interface.
return formattedResults as any;
}

export function removeFileContent({
filePath,
fileType,
failureReason,
projectType,
}: IacFileParsed | IacFileParseFailure): SafeAnalyticsOutput {
return {
filePath,
fileType,
failureReason,
projectType,
};
}
7 changes: 6 additions & 1 deletion src/cli/commands/test/iac-local-execution/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ export interface OpaWasmInstance {
setData: (data: Record<string, any>) => void;
}

export type SafeAnalyticsOutput = Omit<
IacFileParsed | IacFileParseFailure,
'fileContent' | 'jsonContent' | 'engineType'
>;

export enum EngineType {
Kubernetes,
Terraform,
Expand All @@ -70,7 +75,7 @@ export interface PolicyMetadata {
}

export interface IacOptionFlags {
iacDirFiles?: Array<IacFileData>;
iacDirFiles?: Array<IacFileInDirectory>;
severityThreshold?: SEVERITY;
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export function postAnalytics(
queryStringParams['org'] = data.org;
}

debug('analytics', data);
debug('analytics', JSON.stringify(data, null, ' '));

const queryString =
Object.keys(queryStringParams).length > 0
Expand Down
13 changes: 13 additions & 0 deletions test/fixtures/iac/file-logging/file_content_logging.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# NOTE: Kubernetes file with no issues used to detect
# if our analytics/logs contain file content.
# PRIVATE_FILE_CONTENT_CHECK
apiVersion: v1
kind: Pod
metadata:
name: example
spec:
containers:
- name: example
image: example:latest
securityContext:
privileged: false
64 changes: 64 additions & 0 deletions test/iac-unit-tests/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
jest.mock('../../src/cli/commands/test/iac-local-execution/local-cache');
jest.mock('../../src/cli/commands/test/iac-local-execution/file-loader');
jest.mock('../../src/cli/commands/test/iac-local-execution/file-parser', () => {
const { IacProjectType } = require('../../src/lib/iac/constants');
const {
EngineType,
} = require('../../src/cli/commands/test/iac-local-execution/types');
const parsedFiles: IacFileParsed[] = [
{
engineType: EngineType.Terraform,
fileContent: 'FAKE_FILE_CONTENT',
jsonContent: {},
filePath: './storage/storage.tf',
fileType: 'tf',
failureReason: 'Mock Test',
projectType: IacProjectType.TERRAFORM,
},
];
return {
parseFiles: async () => ({ parsedFiles, failedFiles: [] }),
};
});
jest.mock(
'../../src/cli/commands/test/iac-local-execution/file-scanner',
() => {
return {
scanFiles: async () => [],
};
},
);
jest.mock('../../src/lib/detect', () => ({
isLocalFolder: () => true,
}));

import { test } from '../../src/cli/commands/test/iac-local-execution';
import {
IacFileParsed,
IacOptionFlags,
} from '../../src/cli/commands/test/iac-local-execution/types';
import { IacProjectType } from '../../src/lib/iac/constants';

describe('test()', () => {
it('extends the options object with iacDirFiles when a local directory is provided', async () => {
const opts: IacOptionFlags = {};
await test('./storage/', opts);

expect(opts.iacDirFiles).toEqual([
{
filePath: './storage/storage.tf',
fileType: 'tf',
failureReason: 'Mock Test',
projectType: IacProjectType.TERRAFORM,
},
]);
expect(opts.iacDirFiles).not.toEqual(
expect.arrayContaining([
{
fileContent: 'FAKE_FILE_CONTENT',
jsonContent: {},
},
]),
);
});
});
17 changes: 15 additions & 2 deletions test/smoke/spec/iac/snyk_test_local_exec_spec.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
#shellcheck shell=sh

Describe "Snyk iac test --experimental command"
Skip if "execute only in regression test" check_if_regression_test
Skip if "execute only in regression test" check_if_regression_test

Before snyk_login
After snyk_logout

Describe "logging regression tests"
It "does not include file content in analytics logs"
# Run with the -d flag on directory to output network requests and analytics data.
When run snyk iac test ../fixtures/iac/file-logging -d --experimental
# We expect the output, specifically the analytics block not to include
# the following text from the file.
The status should be success
The output should not include "PRIVATE_FILE_CONTENT_CHECK"
The error should not include "PRIVATE_FILE_CONTENT_CHECK"
End
End

Describe "k8s single file scan"
It "finds issues in k8s file"
When run snyk iac test ../fixtures/iac/kubernetes/pod-privileged.yaml --experimental
Expand Down Expand Up @@ -71,7 +84,7 @@ Describe "Snyk iac test --experimental command"
End

# TODO: currently skipped because the parser we're using doesn't fail on invalid terraform
# will be fixed before beta
# will be fixed before beta
xIt "outputs an error for invalid terraforom files"
When run snyk iac test ../fixtures/iac/terraform/sg_open_ssh_invalid_hcl2.tf --experimental
The status should be failure
Expand Down

0 comments on commit 183f676

Please sign in to comment.