Skip to content

Commit

Permalink
Merge pull request #2467 from snyk/feat/iac-yaml-support
Browse files Browse the repository at this point in the history
#### What does this PR do?

This PR bumps @open-policy-agent/opa-wasm to [1.6.0](https://github.com/open-policy-agent/npm-opa-wasm/releases/tag/1.6.0) to include support for the `yaml.unmarshal()` function in Rego and support for Node 10. This allows the `snyk iac` command to support additional policies that unmarshall YAML content within Terraform configuration.

#### Where should the reviewer start?

package.json is the primary change here but the implementation of `yaml.unmarshal()` is here: open-policy-agent/npm-opa-wasm#100

This also removes the use of the `mock-fs` package in the file-scanner.spec.ts test as the opa-wasm package will use `console.error` to write out a warning to stderr when loading the wasm fixture and this somehow causes `mock-fs` to throw the following error bringing the test suite down:

```
ENOENT: no such file or directory, lstat '/Users/Aron/Code/snyk/node_modules/@jest/console/node_modules'
``` 

Rather than debug this weird behavior we've decided to just mock out the function that loads the fixtures directly in the test suite.

#### How should this be manually tested?

[rules.zip](https://github.com/snyk/snyk/files/7719060/rules.zip)

Download the above zip file containing a custom rules bundle and unzip:

With the `snyk-iac-rules` tool build a custom bundle:
```
% snyk-iac-rules build
```

Then test the fixture with the latest snyk cli:

```
% snyk-dev iac test --rules=bundle.tar.gz rules/HELLO/fixtures/sg.tf
```

You should see 15 issues found vs. 14 when run with current snyk.

#### What are the relevant tickets?

[CFG-1271]
  • Loading branch information
aron committed Jan 4, 2022
2 parents 9bacb09 + ce9fbe4 commit 0c76461
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 53 deletions.
43 changes: 14 additions & 29 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"author": "snyk.io",
"license": "Apache-2.0",
"dependencies": {
"@open-policy-agent/opa-wasm": "^1.2.0",
"@open-policy-agent/opa-wasm": "^1.6.0",
"@snyk/cli-interface": "2.11.0",
"@snyk/cloud-config-parser": "^1.12.0",
"@snyk/code-client": "^4.5.0",
Expand Down
Binary file modified test/fixtures/iac/custom-rules/custom.tar.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion test/jest/acceptance/iac/custom-rules.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe('iac test --rules', () => {
expect(stdout).toContain('Testing ./iac/terraform/sg_open_ssh.tf');
expect(stdout).toContain('Infrastructure as code issues:');
expect(stdout).toContain('Missing tags');
expect(stdout).toContain('CUSTOM-123');
expect(stdout).toContain('CUSTOM-1');
expect(stdout).toContain(
'introduced by input > resource > aws_security_group[allow_ssh] > tags',
);
Expand Down
65 changes: 43 additions & 22 deletions test/jest/unit/iac-unit-tests/file-scanner.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import * as mockFs from 'mock-fs';
import * as path from 'path';
import {
scanFiles,
clearPolicyEngineCache,
} from '../../../../src/cli/commands/test/iac-local-execution/file-scanner';
import { LOCAL_POLICY_ENGINE_DIR } from '../../../../src/cli/commands/test/iac-local-execution/local-cache';
import { IacFileParsed } from '../../../../src/cli/commands/test/iac-local-execution/types';
import {
EngineType,
IacFileParsed,
} from '../../../../src/cli/commands/test/iac-local-execution/types';

import {
paresdKubernetesFileStub,
Expand All @@ -15,6 +17,7 @@ import {
expectedViolatedPoliciesForTerraform,
expectedViolatedPoliciesForArm,
} from './file-scanner.fixtures';
import * as localCacheModule from '../../../../src/cli/commands/test/iac-local-execution/local-cache';

describe('scanFiles', () => {
const parsedFiles: Array<IacFileParsed> = [
Expand All @@ -24,23 +27,48 @@ describe('scanFiles', () => {
];

afterEach(() => {
mockFs.restore();
clearPolicyEngineCache();
});

describe('with parsed files', () => {
it('returns the expected violated policies', async () => {
mockFs({
[path.resolve(
__dirname,
path.join('../../../..', LOCAL_POLICY_ENGINE_DIR),
)]: mockFs.load(
path.resolve(
__dirname,
path.join('../../../smoke', LOCAL_POLICY_ENGINE_DIR),
),
),
});
const policyEngineCoreDataPath = path.resolve(
__dirname,
path.join('../../../smoke', LOCAL_POLICY_ENGINE_DIR),
);
const policyEngineMetaDataPath = path.resolve(
__dirname,
path.join('../../../smoke', LOCAL_POLICY_ENGINE_DIR),
);

const spy = jest
.spyOn(localCacheModule, 'getLocalCachePath')
.mockImplementation((engineType: EngineType) => {
switch (engineType) {
case EngineType.Kubernetes:
return [
`${policyEngineCoreDataPath}/k8s_policy.wasm`,
`${policyEngineMetaDataPath}/k8s_data.json`,
];
case EngineType.Terraform:
return [
`${policyEngineCoreDataPath}/tf_policy.wasm`,
`${policyEngineMetaDataPath}/tf_data.json`,
];
case EngineType.CloudFormation:
return [
`${policyEngineCoreDataPath}/cloudformation_policy.wasm`,
`${policyEngineMetaDataPath}/cloudformation_data.json`,
];
case EngineType.ARM:
return [
`${policyEngineCoreDataPath}/arm_policy.wasm`,
`${policyEngineMetaDataPath}/arm_data.json`,
];
default:
return [];
}
});

const scanResults = await scanFiles(parsedFiles);
expect(scanResults[0].violatedPolicies).toEqual(
Expand All @@ -52,20 +80,13 @@ describe('scanFiles', () => {
expect(scanResults[2].violatedPolicies).toEqual(
expectedViolatedPoliciesForArm,
);
spy.mockReset();
});

// TODO: Extract policy engine & the cache mechanism, test them separately.
});

describe('missing policy engine wasm files', () => {
it('throws an error', async () => {
mockFs({
[path.resolve(
__dirname,
path.join('../../../..', LOCAL_POLICY_ENGINE_DIR),
)]: {},
});

await expect(scanFiles(parsedFiles)).rejects.toThrow();
});
});
Expand Down

0 comments on commit 0c76461

Please sign in to comment.