forked from snyk/cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request snyk#2629 from snyk/feat/add-path-arg-for-ignore
Feat: Add path argument for ignore [CFG-1489]
- Loading branch information
Showing
5 changed files
with
325 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
|
||
## Usage | ||
|
||
`snyk ignore --id=<ISSUE_ID> [--expiry=<EXPIRY>] [--reason=<REASON>] [<OPTIONS>]` | ||
`snyk ignore --id=<ISSUE_ID> [--expiry=<EXPIRY>] [--path=<PATH_TO_RESOURCE>] [--reason=<REASON>] [<OPTIONS>]` | ||
|
||
## Description | ||
|
||
|
@@ -11,7 +11,7 @@ The `snyk ignore` command modifies the `.snyk` policy file to ignore a certain i | |
```yaml | ||
ignore: | ||
'<ISSUE_ID>': | ||
- '*': | ||
- '<PATH>': | ||
reason: <REASON> | ||
expires: <EXPIRY> | ||
``` | ||
|
@@ -30,10 +30,24 @@ Snyk ID for the issue to ignore. Required. | |
|
||
Expiry date in a format `YYYY-MM-DD` ([ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) and [RFC 2822](https://tools.ietf.org/html/rfc2822) are supported). | ||
|
||
### `--path=<PATH_TO_RESOURCE>` | ||
|
||
Path to resource for which to ignore the issue. Use to narrow the scope of the ignore rule. When no resource path is specified, all resources are ignored. | ||
|
||
### `--reason=<REASON>` | ||
|
||
Human-readable `<REASON>` to ignore this issue. | ||
|
||
## Example: ignore a specific vulnerability | ||
## Examples | ||
|
||
### Ignore a specific vulnerability: | ||
|
||
`$ snyk ignore --id='npm:qs:20170213' --expiry='2021-01-10' --reason='Module not affected by this vulnerability'` | ||
``` | ||
$ snyk ignore --id='npm:qs:20170213' --expiry='2021-01-10' --reason='Module not affected by this vulnerability' | ||
``` | ||
### Ignore a specific vulnerability with a specified resource path: | ||
``` | ||
$ snyk ignore --id='SNYK-JS-PATHPARSE-1077067' --expiry='2022-01-31' --path='[email protected] > [email protected] > [email protected]' --reason='Not currently exploitable.' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,243 @@ | ||
import { load as loadPolicy } from 'snyk-policy'; | ||
import { fakeServer } from '../../../acceptance/fake-server'; | ||
import { createProjectFromWorkspace } from '../../util/createProject'; | ||
import { requireSnykToken } from '../../util/requireSnykToken'; | ||
import { runSnykCLI, runSnykCLIWithArray } from '../../util/runSnykCLI'; | ||
|
||
jest.setTimeout(1000 * 60); | ||
|
||
describe('snyk ignore', () => { | ||
let server: ReturnType<typeof fakeServer>; | ||
let env: Record<string, string>; | ||
|
||
beforeAll((done) => { | ||
const apiPath = '/api/v1'; | ||
const apiPort = process.env.PORT || process.env.SNYK_PORT || '12345'; | ||
env = { | ||
...process.env, | ||
SNYK_API: 'http://localhost:' + apiPort + apiPath, | ||
SNYK_HOST: 'http://localhost:' + apiPort, | ||
SNYK_TOKEN: requireSnykToken(), | ||
SNYK_DISABLE_ANALYTICS: '1', | ||
}; | ||
|
||
server = fakeServer(apiPath, env.SNYK_TOKEN); | ||
server.listen(apiPort, () => done()); | ||
}); | ||
|
||
afterEach(() => { | ||
server.restore(); | ||
}); | ||
|
||
afterAll((done) => { | ||
server.close(() => done()); | ||
}); | ||
|
||
it('creates a policy file using minimal options', async () => { | ||
const project = await createProjectFromWorkspace('empty'); | ||
const { code } = await runSnykCLI(`ignore --id=ID`, { | ||
cwd: project.path(), | ||
env: env, | ||
}); | ||
|
||
expect(code).toEqual(0); | ||
|
||
const policy = await loadPolicy(project.path()); | ||
expect(policy).toMatchObject({ | ||
ignore: { | ||
ID: [ | ||
{ | ||
'*': { | ||
reason: 'None Given', | ||
expires: expect.any(Date), | ||
created: expect.any(Date), | ||
}, | ||
}, | ||
], | ||
}, | ||
}); | ||
}); | ||
|
||
it('creates a policy file using provided options', async () => { | ||
const project = await createProjectFromWorkspace('empty'); | ||
const { code } = await runSnykCLI( | ||
`ignore --id=ID --reason=REASON --expiry=2017-10-07 --policy-path=${project.path()}`, | ||
{ | ||
cwd: project.path(), | ||
env: env, | ||
}, | ||
); | ||
|
||
expect(code).toEqual(0); | ||
const policy = await loadPolicy(project.path()); | ||
expect(policy).toMatchObject({ | ||
ignore: { | ||
ID: [ | ||
{ | ||
'*': { | ||
reason: 'REASON', | ||
expires: new Date('2017-10-07'), | ||
created: expect.any(Date), | ||
}, | ||
}, | ||
], | ||
}, | ||
}); | ||
}); | ||
|
||
it('correctly creates ignore rules for multiple paths', async () => { | ||
// Arrange | ||
const issueId = 'ID'; | ||
|
||
const paths = ['a > b > c[key] > d', 'x > y[key] > z']; | ||
|
||
const dateStr = '2017-10-07'; | ||
|
||
const ignoreArgs = { | ||
reason: 'REASON', | ||
expires: new Date(dateStr), | ||
}; | ||
|
||
const project = await createProjectFromWorkspace('empty'); | ||
|
||
// Act | ||
await runSnykCLIWithArray( | ||
[ | ||
'ignore', | ||
`--id=${issueId}`, | ||
`--path=${paths[0]}`, | ||
`--expiry=${dateStr}`, | ||
`--reason=${ignoreArgs.reason}`, | ||
], | ||
{ | ||
cwd: project.path(), | ||
env: env, | ||
}, | ||
); | ||
|
||
await runSnykCLIWithArray( | ||
[ | ||
'ignore', | ||
`--id=${issueId}`, | ||
`--path=${paths[1]}`, | ||
`--expiry=${dateStr}`, | ||
`--reason=${ignoreArgs.reason}`, | ||
], | ||
{ | ||
cwd: project.path(), | ||
env: env, | ||
}, | ||
); | ||
|
||
// Assert | ||
const policy = await loadPolicy(project.path()); | ||
expect(policy).toMatchObject({ | ||
ignore: { | ||
[issueId]: [ | ||
{ | ||
[paths[0]]: { | ||
...ignoreArgs, | ||
created: expect.any(Date), | ||
}, | ||
}, | ||
{ | ||
[paths[1]]: { | ||
...ignoreArgs, | ||
created: expect.any(Date), | ||
}, | ||
}, | ||
], | ||
}, | ||
}); | ||
}); | ||
|
||
it('correctly updates an ignore rule when given an existing resource paths', async () => { | ||
// Arrange | ||
const issueId = 'ID'; | ||
|
||
const path = 'a > b > c'; | ||
|
||
const dateStrs = ['2017-10-07', '2019-10-07']; | ||
|
||
const ignoreArgs1 = { | ||
reason: 'REASON1', | ||
expires: new Date(dateStrs[0]), | ||
}; | ||
|
||
const ignoreArgs2 = { | ||
reason: 'REASON2', | ||
expires: new Date(dateStrs[1]), | ||
}; | ||
|
||
const project = await createProjectFromWorkspace('empty'); | ||
|
||
// Act | ||
await runSnykCLIWithArray( | ||
[ | ||
'ignore', | ||
`--id=${issueId}`, | ||
`--path=${path}`, | ||
`--expiry=${dateStrs[0]}`, | ||
`--reason=${ignoreArgs1.reason}`, | ||
], | ||
{ | ||
cwd: project.path(), | ||
env: env, | ||
}, | ||
); | ||
|
||
await runSnykCLIWithArray( | ||
[ | ||
'ignore', | ||
`--id=${issueId}`, | ||
`--path=${path}`, | ||
`--expiry=${dateStrs[1]}`, | ||
`--reason=${ignoreArgs2.reason}`, | ||
], | ||
{ | ||
cwd: project.path(), | ||
env: env, | ||
}, | ||
); | ||
|
||
// Assert | ||
const policy = await loadPolicy(project.path()); | ||
|
||
expect(policy).toMatchObject({ | ||
ignore: { | ||
[issueId]: [ | ||
{ | ||
[path]: { | ||
...ignoreArgs2, | ||
created: expect.any(Date), | ||
}, | ||
}, | ||
], | ||
}, | ||
}); | ||
}); | ||
|
||
it('fails on missing ID', async () => { | ||
const project = await createProjectFromWorkspace('empty'); | ||
const { code, stdout } = await runSnykCLI(`ignore --reason=REASON`, { | ||
cwd: project.path(), | ||
env: env, | ||
}); | ||
|
||
expect(code).toEqual(2); | ||
expect(stdout).toMatch('id is a required field'); | ||
}); | ||
|
||
it('errors when user is not authorized to ignore', async () => { | ||
const project = await createProjectFromWorkspace('empty'); | ||
server.unauthorizeAction('cliIgnore', 'not allowed'); | ||
|
||
const { code, stdout } = await runSnykCLI(`ignore --id=ID`, { | ||
cwd: project.path(), | ||
env, | ||
}); | ||
|
||
expect(code).toEqual(0); | ||
expect(stdout).toMatch('not allowed'); | ||
}); | ||
}); |
Oops, something went wrong.