Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/lib/ecosystems/monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ export async function getFormattedMonitorOutput(
ok: true,
data: monOutput,
path: monitorResult.path,
projectName: monitorResult.id,
projectName: monitorResult.projectName,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changes look good. I have only one question, do you think having the a non unique project name reported for base image/ application project could break any automation around the json output?
Current behavior: json output for node:lates
cat json_output | jq '.[].projectName' "bae0b739-9d1c-4e04-99ac-3e7af3faa271" "73e39537-0bf5-45ed-9621-06d83dc9d69f"

the projectName will be same for both projects

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should not actually be the same projectName for both projects. One will have a target file appended. For example, when setting --project-name=brians_project on a container with a JS application, there are two different projects created:

  • brians_project:/usr/lib/node_modules (JS app)
  • brians_project (base image)

});
}
for (const monitorError of errors) {
Expand Down
27 changes: 27 additions & 0 deletions test/fixtures/container-projects/container-deb-scan-result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"identity": {
"type": "deb"
},
"facts": [
{
"type": "depGraph",
"data": {
"schemaVersion": "1.2.0",
"pkgManager": {
"name": "deb",
"repositories": [{"alias": "debian:11"}]
},
"pkgs": [{"id": "alpine@3.18", "info": {"name": "alpine", "version": "3.18"}}],
"graph": {
"rootNodeId": "root-node",
"nodes": [{"nodeId": "root-node", "pkgId": "alpine@3.18", "deps": []}]
}
}
}
],
"target": {
"image": "alpine:latest"
},
"name": "my-custom-project-name"
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"ok": true,
"org": "test-org",
"id": "7c7305e2-fbcb-44d7-8fbf-8367371c509f",
"isMonitored": true,
"licensesPolicy": null,
"uri": "https://app.snyk.io/org/test-org/project/3dda9b21-ca42-4de6-be7a-85696fa6e866/history/f60dce17-8a72-4cca-8a76-e9c88df546aa",
"trialStarted": false,
"path": "/srv",
"projectName": "my-custom-project-name"
}

19 changes: 17 additions & 2 deletions test/jest/acceptance/snyk-container/container.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ describe('snyk container', () => {
});
}

const TEST_DISTROLESS_STATIC_IMAGE =
'gcr.io/distroless/static@sha256:7198a357ff3a8ef750b041324873960cf2153c11cc50abb9d8d5f8bb089f6b4e';
const TEST_DISTROLESS_STATIC_IMAGE_NAME = 'gcr.io/distroless/static';
const TEST_DISTROLESS_STATIC_IMAGE = `${TEST_DISTROLESS_STATIC_IMAGE_NAME}@sha256:7198a357ff3a8ef750b041324873960cf2153c11cc50abb9d8d5f8bb089f6b4e`;
const TEST_DISTROLESS_STATIC_IMAGE_DEPGRAPH = {
schemaVersion: '1.3.0',
pkgManager: {
Expand Down Expand Up @@ -675,6 +675,7 @@ DepGraph end`,
expect.objectContaining({
ok: true,
packageManager: 'deb',
projectName: `docker-image|${TEST_DISTROLESS_STATIC_IMAGE_NAME}`,
manageUrl: expect.stringContaining('://'),
scanResult: expect.objectContaining({
facts: expect.arrayContaining([
Expand Down Expand Up @@ -709,6 +710,7 @@ DepGraph end`,
expect.objectContaining({
ok: true,
packageManager: 'deb',
projectName: 'docker-image|snyk/snyk',
manageUrl: expect.stringContaining('://'),
scanResult: expect.objectContaining({
facts: expect.arrayContaining([
Expand All @@ -731,6 +733,7 @@ DepGraph end`,
expect.objectContaining({
ok: true,
packageManager: 'gomodules',
projectName: 'docker-image|snyk/snyk:/usr/local/bin/snyk',
manageUrl: expect.stringContaining('://'),
scanResult: expect.objectContaining({
facts: expect.arrayContaining([
Expand All @@ -748,6 +751,18 @@ DepGraph end`,
]),
);
});

it('snyk container monitor json returns custom projectName when --project-name is provided', async () => {
const customProjectName = 'my-custom-project-name';
const { code, stdout } = await runSnykCLI(
`container monitor --platform=linux/amd64 --project-name=${customProjectName} --json ${TEST_DISTROLESS_STATIC_IMAGE}`,
);
expect(code).toEqual(0);
const result = JSON.parse(stdout);

// projectName should match the --project-name flag value
expect(result.projectName).toBe(customProjectName);
});
});

describe('snyk container monitor supports --target-reference', () => {
Expand Down
48 changes: 48 additions & 0 deletions test/jest/unit/ecosystems-monitor-docker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,52 @@ describe('monitorEcosystem docker/container', () => {
makeRequestSpy.mock.calls[0][0].body.pruneRepeatedSubdependencies,
).toBeUndefined();
});

it('should return projectName from registry response in JSON output', async () => {
const containerScanResult = readJsonFixture(
'container-deb-scan-result.json',
) as ScanResult;
const monitorDependenciesResponse = readJsonFixture(
'monitor-dependencies-response-with-project-name.json',
) as ecosystemsTypes.MonitorDependenciesResponse;

jest
.spyOn(dockerPlugin, 'scan')
.mockResolvedValue({ scanResults: [containerScanResult] });
jest
.spyOn(request, 'makeRequest')
.mockResolvedValue(monitorDependenciesResponse);

const results: Array<GoodResult | BadResult> = [];

const [monitorResults, monitorErrors] = await ecosystems.monitorEcosystem(
'docker',
['/srv'],
{
path: '/srv',
docker: true,
org: 'test-org',
},
);

const jsonOutput = await getFormattedMonitorOutput(
results,
monitorResults,
monitorErrors,
{
path: '/srv',
docker: true,
org: 'test-org',
json: true,
} as Options,
);

const parsedOutput = JSON.parse(jsonOutput);

// projectName should be the actual project name from the registry, not the id (UUID)
expect(parsedOutput.projectName).toBe('my-custom-project-name');
expect(parsedOutput.projectName).not.toBe(
'7c7305e2-fbcb-44d7-8fbf-8367371c509f',
);
});
});