diff --git a/src/cli/commands/test/iac/local-execution/types.ts b/src/cli/commands/test/iac/local-execution/types.ts index 44c9f6799a..96d26ba9e0 100644 --- a/src/cli/commands/test/iac/local-execution/types.ts +++ b/src/cli/commands/test/iac/local-execution/types.ts @@ -212,6 +212,8 @@ export type IaCTestFlags = Pick< path?: string; // Allows the caller to provide the path to a WASM bundle. rules?: string; + // Enables Snyk Cloud custom rules + 'custom-rules'?: boolean; 'cloud-context'?: string; 'snyk-cloud-environment'?: string; // Tags and attributes @@ -400,6 +402,7 @@ export enum IaCErrorCodes { FailedToProcessResults = 2200, EntitlementNotEnabled = 2201, ReadSettings = 2202, + FeatureFlagNotEnabled = 2203, } export interface TestReturnValue { diff --git a/src/cli/commands/test/iac/v2/assert-iac-options.ts b/src/cli/commands/test/iac/v2/assert-iac-options.ts index 7f1fe2f62a..6e296e243f 100644 --- a/src/cli/commands/test/iac/v2/assert-iac-options.ts +++ b/src/cli/commands/test/iac/v2/assert-iac-options.ts @@ -30,6 +30,8 @@ const keys: (keyof IaCTestFlags)[] = [ 'detectionDepth', 'cloud-context', 'snyk-cloud-environment', + 'custom-rules', + 'experimental', // PolicyOptions 'ignore-policy', 'policy-path', diff --git a/src/cli/commands/test/iac/v2/index.ts b/src/cli/commands/test/iac/v2/index.ts index 500cff0fe2..14f9eb996f 100644 --- a/src/cli/commands/test/iac/v2/index.ts +++ b/src/cli/commands/test/iac/v2/index.ts @@ -55,6 +55,8 @@ async function prepareTestConfig( const cloudContext = getFlag(options, 'cloud-context'); const snykCloudEnvironment = getFlag(options, 'snyk-cloud-environment'); const insecure = options.insecure; + const customRules = options['custom-rules']; + const experimental = options.experimental; return { paths, @@ -74,5 +76,7 @@ async function prepareTestConfig( snykCloudEnvironment, insecure, org, + customRules, + experimental, }; } diff --git a/src/lib/formatters/iac-output/text/formatters.ts b/src/lib/formatters/iac-output/text/formatters.ts index 2713feeeec..09f351a5a7 100644 --- a/src/lib/formatters/iac-output/text/formatters.ts +++ b/src/lib/formatters/iac-output/text/formatters.ts @@ -200,6 +200,7 @@ function formatSnykIacTestScanVulnerability( impact: vulnerability.rule.description, resolve, documentation: vulnerability.rule.documentation, + isGeneratedByCustomRule: vulnerability.rule.isGeneratedByCustomRule, remediation: { [iacRemediationTypes[vulnerability.resource.kind]]: resolve, }, diff --git a/src/lib/iac/test/v2/errors.ts b/src/lib/iac/test/v2/errors.ts index 2bb5d24462..18eea65074 100644 --- a/src/lib/iac/test/v2/errors.ts +++ b/src/lib/iac/test/v2/errors.ts @@ -50,6 +50,10 @@ export function getErrorUserMessage(code: number, error: string): string { return `${error}. Please run the command again with the \`-d\` flag for more information.`; } + if (code == IaCErrorCodes.FeatureFlagNotEnabled) { + return error; + } + return snykIacTestErrorsUserMessages[errorName]; } diff --git a/src/lib/iac/test/v2/json.ts b/src/lib/iac/test/v2/json.ts index 22114de14e..4bf063ba65 100644 --- a/src/lib/iac/test/v2/json.ts +++ b/src/lib/iac/test/v2/json.ts @@ -67,7 +67,7 @@ export interface IacIssue { isIgnored: boolean; iacDescription: IacDescription; lineNumber: number; - documentation: string; + documentation?: string; isGeneratedByCustomRule: boolean; path: string[]; policyEngineType?: string; @@ -263,7 +263,7 @@ function vulnerabilitiesToIacIssues( }, lineNumber: v.resource.line || -1, documentation: v.rule.documentation, // only works for rules available on snyk.io - isGeneratedByCustomRule: false, + isGeneratedByCustomRule: !!v.rule.isGeneratedByCustomRule, path: v.resource.path || [], // needs to be fixed, currently doesn't show the full path compliance: [], description: v.rule.description, diff --git a/src/lib/iac/test/v2/scan/index.ts b/src/lib/iac/test/v2/scan/index.ts index c082894cdb..33a74b44a9 100644 --- a/src/lib/iac/test/v2/scan/index.ts +++ b/src/lib/iac/test/v2/scan/index.ts @@ -155,6 +155,16 @@ function processFlags( flags.push('-org', options.org); } + if (options.customRules) { + if (options.experimental) { + flags.push('-custom-rules'); + } else { + debug( + '--custom-rules specified without --experimental. ignoring --custom-rules.', + ); + } + } + return flags; } diff --git a/src/lib/iac/test/v2/scan/results.ts b/src/lib/iac/test/v2/scan/results.ts index 10d7e5fcbb..d3846b618a 100644 --- a/src/lib/iac/test/v2/scan/results.ts +++ b/src/lib/iac/test/v2/scan/results.ts @@ -99,7 +99,8 @@ export interface Rule { references?: string; labels?: string[]; category?: string; - documentation: string; // TODO: revisit this field when adding support for custom rules + documentation?: string; + isGeneratedByCustomRule?: boolean; } export interface Resource { diff --git a/src/lib/iac/test/v2/types.ts b/src/lib/iac/test/v2/types.ts index 694d433c70..928a5326df 100644 --- a/src/lib/iac/test/v2/types.ts +++ b/src/lib/iac/test/v2/types.ts @@ -18,4 +18,6 @@ export interface TestConfig { snykCloudEnvironment?: string; insecure?: boolean; org?: string; + customRules?: boolean; + experimental?: boolean; }