Skip to content

Commit

Permalink
Merge pull request #3046 from snyk/feat/drift-exclude
Browse files Browse the repository at this point in the history
Change `iac gen-driftignore` to `iac update-exclude-policy`
  • Loading branch information
eliecharra authored Mar 29, 2022
2 parents dd5d9d5 + 9ac4cf1 commit 9c44e4d
Show file tree
Hide file tree
Showing 15 changed files with 429 additions and 259 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ src/cli/commands/test/iac-output.ts @snyk/group-infrastructure-as-code
src/cli/commands/test/iac-test-shim.ts @snyk/group-infrastructure-as-code
src/cli/commands/describe.ts @snyk/group-infrastructure-as-code
src/cli/commands/report/ @snyk/group-infrastructure-as-code
src/cli/commands/gen-driftignore.ts @snyk/group-infrastructure-as-code
src/cli/commands/update-exclude-policy.ts @snyk/group-infrastructure-as-code
src/cli/commands/apps @snyk/moose
src/lib/apps @snyk/moose
src/lib/cloud-config-projects.ts @snyk/group-infrastructure-as-code
Expand Down
66 changes: 0 additions & 66 deletions help/cli-commands/iac-gen-driftignore.md

This file was deleted.

46 changes: 46 additions & 0 deletions help/cli-commands/iac-update-exclude-policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# snyk iac update-exclude-policy -- generate ignore rules based on scan result

## Usage

`snyk iac update-exclude-policy [<OPTIONS>]`

## Description

The `snyk iac update-exclude-policy` can generate exclude policy rules to be used by `snyk iac scan`.

## Exit codes

Possible exit codes and their meaning:

**0**: success, exclude rules generated successfully
**1**: error, something wrong happened during exclude rules generation

## Configure the Snyk CLI

You can use environment variables to configure the Snyk CLI and also set variables to configure the Snyk CLI to connect with the Snyk API.
See [Configure the Snyk CLI](https://docs.snyk.io/features/snyk-cli/configure-the-snyk-cli).

## Debug

Use the `-d` option to output the debug logs.

## Options

### `--exclude-changed`

Exclude resources that changed on cloud provider

### `--exclude-missing`

Exclude missing resources

### `--exclude-unmanaged`

Exclude resources not managed by IaC

## Usage

```
$ snyk iac scan --output=json://output.json
$ snyk iac describe --json --all | snyk iac update-exclude-policy
```
36 changes: 0 additions & 36 deletions src/cli/commands/gen-driftignore.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/cli/commands/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ async function callModule(mod, args) {
const commands = {
auth: async (...args) => callModule(import('./auth'), args),
config: async (...args) => callModule(import('./config'), args),
'gen-driftignore': async (...args) =>
callModule(import('./gen-driftignore'), args),
'update-exclude-policy': async (...args) =>
callModule(import('./update-exclude-policy'), args),
describe: async (...args) => callModule(import('./describe'), args),
help: async (...args) => callModule(import('./help'), args),
ignore: async (...args) => callModule(import('./ignore'), args),
Expand Down
57 changes: 57 additions & 0 deletions src/cli/commands/update-exclude-policy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { MethodArgs } from '../args';
import { processCommandArgs } from './process-command-args';
import * as legacyError from '../../lib/errors/legacy-errors';
import * as fs from 'fs';
import * as snykPolicyLib from 'snyk-policy';
import { getIacOrgSettings } from './test/iac-local-execution/org-settings/get-iac-org-settings';
import { UnsupportedEntitlementCommandError } from './test/iac-local-execution/assert-iac-options-flag';
import config from '../../lib/config';
import {
parseDriftAnalysisResults,
updateExcludeInPolicy,
} from '../../lib/iac/drift';
import { Policy } from '../../lib/policy/find-and-load-policy';

export default async (...args: MethodArgs): Promise<any> => {
const { options } = processCommandArgs(...args);

// Ensure that this update-exclude-policy command can only be runned when using `snyk iac update-exclude-policy`
// Avoid `snyk update-exclude-policy` direct usage
if (options.iac != true) {
return legacyError('update-exclude-policy');
}

// Ensure that we are allowed to run that command
// by checking the entitlement
const orgPublicId = options.org ?? config.org;
const iacOrgSettings = await getIacOrgSettings(orgPublicId);
if (!iacOrgSettings.entitlements?.iacDrift) {
throw new UnsupportedEntitlementCommandError(
'update-exclude-policy',
'iacDrift',
);
}

try {
// There's an open bug for this in Windows in the current version of node when called with no stdinput.
// See https://github.com/nodejs/node/issues/19831
// The actual error handling behavior is enough for now but may be improved if needed
const analysis = parseDriftAnalysisResults(fs.readFileSync(0).toString());
let policy: Policy;
try {
policy = await snykPolicyLib.load();
} catch (error) {
if (error.code === 'ENOENT') {
// policy file does not exist - create it
policy = await snykPolicyLib.create();
} else {
throw error;
}
}
await updateExcludeInPolicy(policy, analysis, options);
await snykPolicyLib.save(policy);
} catch (e) {
const err = new Error('Error running `iac update-exclude-policy` ' + e);
return Promise.reject(err);
}
};
2 changes: 1 addition & 1 deletion src/cli/modes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const modes: Record<string, ModeData> = {
},
},
iac: {
allowedCommands: ['test', 'gen-driftignore', 'describe', 'report'],
allowedCommands: ['test', 'update-exclude-policy', 'describe', 'report'],
config: (args): [] => {
args['iac'] = true;

Expand Down
61 changes: 27 additions & 34 deletions src/lib/iac/drift.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,47 +120,13 @@ export const generateArgs = (
return generateScanFlags(options as DescribeOptions, driftIgnore);
}

if (options.kind === 'gen-driftignore') {
return generateGenDriftIgnoreFlags(options as GenDriftIgnoreOptions);
}

if (options.kind === 'fmt') {
return generateFmtFlags(options as FmtOptions);
}

throw 'Unsupported command';
};

export const generateGenDriftIgnoreFlags = (
options: GenDriftIgnoreOptions,
): string[] => {
const args: string[] = ['gen-driftignore', ...driftctlDefaultOptions];

if (options.input) {
args.push('--input');
args.push(options.input);
}

if (options.output) {
args.push('--output');
args.push(options.output);
}

if (options['exclude-changed']) {
args.push('--exclude-changed');
}

if (options['exclude-missing']) {
args.push('--exclude-missing');
}

if (options['exclude-unmanaged']) {
args.push('--exclude-unmanaged');
}

return args;
};

const generateFmtFlags = (options: FmtOptions): string[] => {
const args: string[] = ['fmt', ...driftctlDefaultOptions];

Expand Down Expand Up @@ -535,6 +501,33 @@ export function driftignoreFromPolicy(policy: Policy | undefined): string[] {
return policy.exclude[excludeSection];
}

export const updateExcludeInPolicy = (
policy: Policy,
analysis: DriftAnalysis,
options: GenDriftIgnoreOptions,
): void => {
const excludedResources = driftignoreFromPolicy(policy);
const addResource = (res) => excludedResources.push(`${res.type}.${res.id}`);

if (!options['exclude-changed'] && analysis.summary.total_changed > 0) {
analysis.differences?.forEach((change) => addResource(change.res));
}

if (!options['exclude-missing'] && analysis.summary.total_missing > 0) {
analysis.missing?.forEach((res) => addResource(res));
}

if (!options['exclude-unmanaged'] && analysis.summary.total_unmanaged > 0) {
analysis.unmanaged?.forEach((res) => addResource(res));
}

if (!policy.exclude) {
policy.exclude = {};
}

policy.exclude['iac-drift'] = excludedResources;
};

export function processDriftctlOutput(
options: DescribeOptions,
stdout: string,
Expand Down
4 changes: 1 addition & 3 deletions src/lib/iac/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ export interface FmtOptions extends DriftCTLOptions {
'html-file-output': string;
}

export interface GenDriftIgnoreOptions extends DriftCTLOptions {
input?: string;
output?: string;
export interface GenDriftIgnoreOptions {
'exclude-changed'?: boolean;
'exclude-missing'?: boolean;
'exclude-unmanaged'?: boolean;
Expand Down
2 changes: 1 addition & 1 deletion src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ export enum SupportedCliCommands {
apps = 'apps',
drift = 'drift',
describe = 'describe',
'gen-driftignore' = 'gen-driftignore',
'update-exclude-policy' = 'update-exclude-policy',
report = 'report',
}

Expand Down
Loading

0 comments on commit 9c44e4d

Please sign in to comment.