diff --git a/help/cli-commands/container-monitor.md b/help/cli-commands/container-monitor.md index 4d941d86ec3..e01b6dda61c 100644 --- a/help/cli-commands/container-monitor.md +++ b/help/cli-commands/container-monitor.md @@ -60,6 +60,12 @@ For more detailed advice, include the path to the Dockerfile for the image. Specify a custom Snyk project name. +### `--target-reference=` + +Specify a reference that differentiates this project, for example, a branch name or version. Projects having the same reference can be grouped based on that reference. + +For more information see [Group projects by branch or version for monitoring](https://docs.snyk.io/snyk-cli/scan-and-maintain-projects-using-the-cli/group-projects-by-branch-or-version-for-monitoring) + ### `--policy-path=` Manually pass a path to a `.snyk` policy file. diff --git a/src/lib/ecosystems/monitor.ts b/src/lib/ecosystems/monitor.ts index 0cb7918f6ea..b9a2a4a76e7 100644 --- a/src/lib/ecosystems/monitor.ts +++ b/src/lib/ecosystems/monitor.ts @@ -105,6 +105,7 @@ export async function generateMonitorDependenciesRequest( // WARNING! This mutates the payload. The project name logic should be handled in the plugin. scanResult.name = options['project-name'] || config.PROJECT_NAME || scanResult.name; + scanResult.targetReference = options['target-reference']; // WARNING! This mutates the payload. Policy logic should be in the plugin. const policy = await findAndLoadPolicyForScanResult(scanResult, options); if (policy !== undefined) { diff --git a/src/lib/types.ts b/src/lib/types.ts index a8df7357ca6..f8d869633a2 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -133,6 +133,7 @@ export interface MonitorOptions { 'project-name'?: string; 'print-deps'?: boolean; 'print-dep-paths'?: boolean; + 'target-reference'?: string; scanAllUnmanaged?: boolean; allProjects?: boolean; // An experimental flag to allow monitoring of bigtrees (with degraded deps info and remediation advice). diff --git a/test/jest/acceptance/snyk-container/container.spec.ts b/test/jest/acceptance/snyk-container/container.spec.ts index 077392ef0c1..8194fb3e389 100644 --- a/test/jest/acceptance/snyk-container/container.spec.ts +++ b/test/jest/acceptance/snyk-container/container.spec.ts @@ -3,6 +3,7 @@ import { startSnykCLI, TestCLI } from '../../util/startSnykCLI'; import { runSnykCLI } from '../../util/runSnykCLI'; import { FakeServer, fakeServer } from '../../../acceptance/fake-server'; import { RunCommandOptions, RunCommandResult } from '../../util/runCommand'; +import { getServerPort } from '../../util/getServerPort'; jest.setTimeout(1000 * 60); @@ -304,6 +305,55 @@ DepGraph end`, }); }); + describe('snyk container monitor supports --target-reference', () => { + let server: ReturnType; + let env: Record; + + beforeAll((done) => { + const port = getServerPort(process); + const baseApi = '/api/v1'; + env = { + ...process.env, + SNYK_API: 'http://localhost:' + port + baseApi, + SNYK_HOST: 'http://localhost:' + port, + SNYK_TOKEN: '123456789', + SNYK_DISABLE_ANALYTICS: '1', + DEBUG: 'snyk*', + }; + server = fakeServer(baseApi, env.SNYK_TOKEN); + server.listen(port, () => { + done(); + }); + }); + + afterEach(() => { + server.restore(); + }); + + afterAll((done) => { + server.close(() => done()); + }); + + it('forwards value of target-reference to monitor-dependencies endpoint', async () => { + const { code } = await runSnykCLI( + `container monitor ${TEST_DISTROLESS_STATIC_IMAGE} --target-reference=test-target-ref`, + { + env, + }, + ); + expect(code).toEqual(0); + + const monitorRequests = server + .getRequests() + .filter((request) => request.url?.includes('/monitor-dependencies')); + + expect(monitorRequests.length).toBeGreaterThanOrEqual(1); + monitorRequests.forEach((request) => { + expect(request.body.scanResult.targetReference).toBe('test-target-ref'); + }); + }); + }); + function assertCliExitCode( code: number, expectedCode: number,