-
Notifications
You must be signed in to change notification settings - Fork 62
Expand file tree
/
Copy pathscan_command.py
More file actions
139 lines (123 loc) · 4.64 KB
/
scan_command.py
File metadata and controls
139 lines (123 loc) · 4.64 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
from typing import Annotated, List, Optional
import click
import typer
from cycode.cli.cli_types import ScanTypeOption, ScaScanTypeOption, SeverityOption
from cycode.cli.consts import (
ISSUE_DETECTED_STATUS_CODE,
NO_ISSUES_STATUS_CODE,
)
from cycode.cli.utils import scan_utils
from cycode.cli.utils.get_api_client import get_scan_cycode_client
from cycode.cli.utils.sentry import add_breadcrumb
_AUTH_RICH_HELP_PANEL = 'Authentication options'
_SCA_RICH_HELP_PANEL = 'SCA options'
def scan_command(
ctx: typer.Context,
scan_type: Annotated[
ScanTypeOption,
typer.Option(
'--scan-type',
'-t',
help='Specify the type of scan you wish to execute.',
case_sensitive=False,
),
] = ScanTypeOption.SECRET,
client_secret: Annotated[
Optional[str],
typer.Option(
help='Specify a Cycode client secret for this specific scan execution.',
rich_help_panel=_AUTH_RICH_HELP_PANEL,
),
] = None,
client_id: Annotated[
Optional[str],
typer.Option(
help='Specify a Cycode client ID for this specific scan execution.',
rich_help_panel=_AUTH_RICH_HELP_PANEL,
),
] = None,
show_secret: Annotated[bool, typer.Option('--show-secret', help='Show Secrets in plain text.')] = False,
soft_fail: Annotated[
bool, typer.Option('--soft-fail', help='Run the scan without failing; always return a non-error status code.')
] = False,
severity_threshold: Annotated[
SeverityOption,
typer.Option(
help='Show violations only for the specified level or higher.',
case_sensitive=False,
),
] = SeverityOption.INFO,
sync: Annotated[
bool,
typer.Option('--sync', help='Run scan synchronously.', show_default='asynchronously'),
] = False,
report: Annotated[
bool,
typer.Option(
'--report',
help='When specified, generates a violations report. '
'A link to the report will be displayed in the console output.',
),
] = False,
sca_scan: Annotated[
List[ScaScanTypeOption],
typer.Option(
help='Specify the type of SCA scan you wish to execute.',
rich_help_panel=_SCA_RICH_HELP_PANEL,
),
] = (ScaScanTypeOption.PACKAGE_VULNERABILITIES, ScaScanTypeOption.LICENSE_COMPLIANCE),
monitor: Annotated[
bool,
typer.Option(
'--monitor',
help='When specified, the scan results are recorded in the Discovery module.',
rich_help_panel=_SCA_RICH_HELP_PANEL,
),
] = False,
no_restore: Annotated[
bool,
typer.Option(
'--no-restore',
help='When specified, Cycode will not run restore command. ' 'Will scan direct dependencies [b]only[/]!',
rich_help_panel=_SCA_RICH_HELP_PANEL,
),
] = False,
gradle_all_sub_projects: Annotated[
bool,
typer.Option(
'--gradle-all-sub-projects',
help='When specified, Cycode will run gradle restore command for all sub projects. '
'Should run from root project directory [b]only[/]!',
rich_help_panel=_SCA_RICH_HELP_PANEL,
),
] = False,
) -> None:
""":magnifying_glass_tilted_right: Scan the content for Secrets, IaC, SCA, and SAST violations.
You'll need to specify which scan type to perform:
[cyan]path[/]/[cyan]repository[/]/[cyan]commit_history[/]."""
add_breadcrumb('scan')
ctx.obj['show_secret'] = show_secret
ctx.obj['soft_fail'] = soft_fail
ctx.obj['client'] = get_scan_cycode_client(client_id, client_secret, not ctx.obj['show_secret'])
ctx.obj['scan_type'] = scan_type
ctx.obj['sync'] = sync
ctx.obj['severity_threshold'] = severity_threshold
ctx.obj['monitor'] = monitor
ctx.obj['report'] = report
_ = no_restore, gradle_all_sub_projects # they are actually used; via ctx.params
_sca_scan_to_context(ctx, sca_scan)
def _sca_scan_to_context(ctx: typer.Context, sca_scan_user_selected: List[str]) -> None:
for sca_scan_option_selected in sca_scan_user_selected:
ctx.obj[sca_scan_option_selected] = True
@click.pass_context
def scan_command_result_callback(ctx: click.Context, *_, **__) -> None:
add_breadcrumb('scan_finalize')
progress_bar = ctx.obj.get('progress_bar')
if progress_bar:
progress_bar.stop()
if ctx.obj['soft_fail']:
raise typer.Exit(0)
exit_code = NO_ISSUES_STATUS_CODE
if scan_utils.is_scan_failed(ctx):
exit_code = ISSUE_DETECTED_STATUS_CODE
raise typer.Exit(exit_code)