-
Notifications
You must be signed in to change notification settings - Fork 62
Expand file tree
/
Copy pathignore_command.py
More file actions
148 lines (128 loc) · 5.13 KB
/
ignore_command.py
File metadata and controls
148 lines (128 loc) · 5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import re
from typing import Annotated, Optional
import click
import typer
from cycode.cli import consts
from cycode.cli.cli_types import ScanTypeOption
from cycode.cli.config import configuration_manager
from cycode.cli.logger import logger
from cycode.cli.utils.path_utils import get_absolute_path, is_path_exists
from cycode.cli.utils.sentry import add_breadcrumb
from cycode.cli.utils.string_utils import hash_string_to_sha256
_FILTER_BY_RICH_HELP_PANEL = 'Filter options'
_SECRETS_FILTER_BY_RICH_HELP_PANEL = 'Secrets filter options'
_SCA_FILTER_BY_RICH_HELP_PANEL = 'SCA filter options'
def _is_package_pattern_valid(package: str) -> bool:
return re.search('^[^@]+@[^@]+$', package) is not None
def ignore_command( # noqa: C901
by_path: Annotated[
Optional[str],
typer.Option(
help='Ignore a specific file or directory while scanning.',
show_default=False,
rich_help_panel=_FILTER_BY_RICH_HELP_PANEL,
),
] = None,
by_rule: Annotated[
Optional[str],
typer.Option(
help='Ignore scanning a specific Secrets rule ID or IaC rule ID.',
show_default=False,
rich_help_panel=_FILTER_BY_RICH_HELP_PANEL,
),
] = None,
by_value: Annotated[
Optional[str],
typer.Option(
help='Ignore a specific value.',
show_default=False,
rich_help_panel=_SECRETS_FILTER_BY_RICH_HELP_PANEL,
),
] = None,
by_sha: Annotated[
Optional[str],
typer.Option(
help='Ignore a specific SHA512 representation of a string.',
show_default=False,
rich_help_panel=_SECRETS_FILTER_BY_RICH_HELP_PANEL,
),
] = None,
by_package: Annotated[
Optional[str],
typer.Option(
help='Ignore scanning a specific package version. Expected pattern: [cyan]name@version[/cyan].',
show_default=False,
rich_help_panel=_SCA_FILTER_BY_RICH_HELP_PANEL,
),
] = None,
by_cve: Annotated[
Optional[str],
typer.Option(
help='Ignore scanning a specific CVE. Expected pattern: [cyan]CVE-YYYY-NNN[/cyan].',
show_default=False,
rich_help_panel=_SCA_FILTER_BY_RICH_HELP_PANEL,
),
] = None,
scan_type: Annotated[
ScanTypeOption,
typer.Option(
'--scan-type',
'-t',
help='Specify the type of scan you wish to execute.',
case_sensitive=False,
),
] = ScanTypeOption.SECRET,
is_global: Annotated[
bool, typer.Option('--global', '-g', help='Add an ignore rule to the global CLI config.')
] = False,
) -> None:
"""Ignores a specific value, path or rule ID."""
add_breadcrumb('ignore')
all_by_values = [by_value, by_sha, by_path, by_rule, by_package, by_cve]
if all(by is None for by in all_by_values):
raise click.ClickException('Ignore by type is missing')
if len([by for by in all_by_values if by is not None]) != 1:
raise click.ClickException('You must specify only one ignore by type')
if any(by is not None for by in [by_value, by_sha]) and scan_type != consts.SECRET_SCAN_TYPE:
raise click.ClickException('This exclude is supported only for Secret scan type')
if (by_cve or by_package) and scan_type != consts.SCA_SCAN_TYPE:
raise click.ClickException('This exclude is supported only for SCA scan type')
# only one of the by values must be set
# at least one of the by values must be set
exclusion_type = exclusion_value = None
if by_value:
exclusion_type = consts.EXCLUSIONS_BY_VALUE_SECTION_NAME
exclusion_value = hash_string_to_sha256(by_value)
if by_sha:
exclusion_type = consts.EXCLUSIONS_BY_SHA_SECTION_NAME
exclusion_value = by_sha
if by_path:
absolute_path = get_absolute_path(by_path)
if not is_path_exists(absolute_path):
raise click.ClickException('The provided path to ignore by does not exist')
exclusion_type = consts.EXCLUSIONS_BY_PATH_SECTION_NAME
exclusion_value = get_absolute_path(absolute_path)
if by_rule:
exclusion_type = consts.EXCLUSIONS_BY_RULE_SECTION_NAME
exclusion_value = by_rule
if by_package:
if not _is_package_pattern_valid(by_package):
raise click.ClickException('wrong package pattern. should be name@version.')
exclusion_type = consts.EXCLUSIONS_BY_PACKAGE_SECTION_NAME
exclusion_value = by_package
if by_cve:
exclusion_type = consts.EXCLUSIONS_BY_CVE_SECTION_NAME
exclusion_value = by_cve
if not exclusion_type or not exclusion_value:
# should never happen
raise click.ClickException('Invalid ignore by type')
configuration_scope = 'global' if is_global else 'local'
logger.debug(
'Adding ignore rule, %s',
{
'configuration_scope': configuration_scope,
'exclusion_type': exclusion_type,
'exclusion_value': exclusion_value,
},
)
configuration_manager.add_exclusion(configuration_scope, scan_type, exclusion_type, exclusion_value)