devsecops-engine-tools 1.16.0__py3-none-any.whl → 1.17.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of devsecops-engine-tools might be problematic. Click here for more details.
- devsecops_engine_tools/engine_core/src/applications/runner_engine_core.py +1 -1
- devsecops_engine_tools/engine_core/src/domain/model/exclusions.py +4 -0
- devsecops_engine_tools/engine_core/src/domain/model/report.py +2 -0
- devsecops_engine_tools/engine_core/src/domain/usecases/handle_risk.py +54 -28
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py +45 -12
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_pretty_table/printer_pretty_table.py +66 -13
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_rich_table/__init__.py +0 -0
- devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_rich_table/printer_rich_table.py +86 -0
- devsecops_engine_tools/engine_risk/src/domain/usecases/break_build.py +20 -11
- devsecops_engine_tools/engine_risk/src/domain/usecases/handle_filters.py +63 -0
- devsecops_engine_tools/engine_risk/src/infrastructure/entry_points/entry_point_risk.py +9 -51
- devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/engagement.py +1 -0
- devsecops_engine_tools/version.py +1 -1
- {devsecops_engine_tools-1.16.0.dist-info → devsecops_engine_tools-1.17.0.dist-info}/METADATA +2 -1
- {devsecops_engine_tools-1.16.0.dist-info → devsecops_engine_tools-1.17.0.dist-info}/RECORD +18 -16
- {devsecops_engine_tools-1.16.0.dist-info → devsecops_engine_tools-1.17.0.dist-info}/WHEEL +0 -0
- {devsecops_engine_tools-1.16.0.dist-info → devsecops_engine_tools-1.17.0.dist-info}/entry_points.txt +0 -0
- {devsecops_engine_tools-1.16.0.dist-info → devsecops_engine_tools-1.17.0.dist-info}/top_level.txt +0 -0
|
@@ -191,8 +191,8 @@ def application_core():
|
|
|
191
191
|
"github": GithubActions(),
|
|
192
192
|
"local": RuntimeLocal(),
|
|
193
193
|
}.get(args["platform_devops"])
|
|
194
|
-
printer_table_gateway = PrinterPrettyTable()
|
|
195
194
|
metrics_manager_gateway = S3Manager()
|
|
195
|
+
printer_table_gateway = PrinterPrettyTable()
|
|
196
196
|
|
|
197
197
|
init_engine_core(
|
|
198
198
|
vulnerability_management_gateway,
|
|
@@ -12,3 +12,7 @@ class Exclusions:
|
|
|
12
12
|
self.severity = kwargs.get("severity", "")
|
|
13
13
|
self.hu = kwargs.get("hu", "")
|
|
14
14
|
self.reason = kwargs.get("reason", "Risk Accepted")
|
|
15
|
+
self.vm_id = kwargs.get("vm_id", "")
|
|
16
|
+
self.vm_id_url = kwargs.get("vm_id_url", "")
|
|
17
|
+
self.service = kwargs.get("service", "")
|
|
18
|
+
self.tags = kwargs.get("tags", [])
|
|
@@ -4,6 +4,8 @@ from dataclasses import dataclass
|
|
|
4
4
|
@dataclass
|
|
5
5
|
class Report:
|
|
6
6
|
def __init__(self, **kwargs):
|
|
7
|
+
self.vm_id = kwargs.get("vm_id", "")
|
|
8
|
+
self.vm_id_url = kwargs.get("vm_id_url", "")
|
|
7
9
|
self.id = kwargs.get("id", [])
|
|
8
10
|
self.vuln_id_from_tool = kwargs.get("vuln_id_from_tool", "")
|
|
9
11
|
self.where = kwargs.get("where", "")
|
|
@@ -51,7 +51,7 @@ class HandleRisk:
|
|
|
51
51
|
"Error getting finding list in handle risk: {0}".format(str(e))
|
|
52
52
|
)
|
|
53
53
|
|
|
54
|
-
def _filter_engagements(self, engagements, service, risk_config):
|
|
54
|
+
def _filter_engagements(self, engagements, service, initial_services, risk_config):
|
|
55
55
|
filtered_engagements = []
|
|
56
56
|
min_word_length = risk_config["HANDLE_SERVICE_NAME"]["MIN_WORD_LENGTH"]
|
|
57
57
|
words = [
|
|
@@ -65,20 +65,22 @@ class HandleRisk:
|
|
|
65
65
|
min_word_amount = risk_config["HANDLE_SERVICE_NAME"]["MIN_WORD_AMOUNT"]
|
|
66
66
|
endings = risk_config["HANDLE_SERVICE_NAME"]["CHECK_ENDING"]
|
|
67
67
|
|
|
68
|
+
initial_services_lower = [service.lower() for service in initial_services]
|
|
69
|
+
|
|
68
70
|
for engagement in engagements:
|
|
69
|
-
if
|
|
70
|
-
filtered_engagements += [engagement
|
|
71
|
+
if engagement.name.lower() in initial_services_lower:
|
|
72
|
+
filtered_engagements += [engagement]
|
|
71
73
|
elif re.search(check_words_regex, engagement.name.lower()) and (
|
|
72
74
|
sum(1 for word in words if word.lower() in engagement.name.lower())
|
|
73
75
|
>= min_word_amount
|
|
74
76
|
):
|
|
75
|
-
filtered_engagements += [engagement
|
|
77
|
+
filtered_engagements += [engagement]
|
|
76
78
|
elif endings:
|
|
77
79
|
if any(
|
|
78
80
|
(service.lower() + ending.lower() == engagement.name.lower())
|
|
79
81
|
for ending in endings
|
|
80
82
|
):
|
|
81
|
-
filtered_engagements += [engagement
|
|
83
|
+
filtered_engagements += [engagement]
|
|
82
84
|
|
|
83
85
|
return filtered_engagements
|
|
84
86
|
|
|
@@ -94,15 +96,28 @@ class HandleRisk:
|
|
|
94
96
|
services_to_exclude = set(
|
|
95
97
|
risk_exclusions[pipeline_name]["SKIP_SERVICE"].get("services", [])
|
|
96
98
|
)
|
|
97
|
-
service_set = set(service_list)
|
|
98
|
-
|
|
99
|
-
remaining_services = list(service_set - services_to_exclude)
|
|
100
|
-
service_excluded = list(service_set & services_to_exclude)
|
|
101
99
|
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
remaining_engagements = [
|
|
101
|
+
engagement
|
|
102
|
+
for engagement in service_list
|
|
103
|
+
if engagement.name.lower()
|
|
104
|
+
not in [service.lower() for service in services_to_exclude]
|
|
105
|
+
]
|
|
106
|
+
excluded_engagements = [
|
|
107
|
+
engagement
|
|
108
|
+
for engagement in service_list
|
|
109
|
+
if engagement.name.lower()
|
|
110
|
+
in [service.lower() for service in services_to_exclude]
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
print(
|
|
114
|
+
f"Services to exclude: {[engagement.name for engagement in excluded_engagements]}"
|
|
115
|
+
)
|
|
116
|
+
logger.info(
|
|
117
|
+
f"Services to exclude: {[engagement.name for engagement in excluded_engagements]}"
|
|
118
|
+
)
|
|
104
119
|
|
|
105
|
-
return
|
|
120
|
+
return remaining_engagements
|
|
106
121
|
return service_list
|
|
107
122
|
|
|
108
123
|
def _should_skip_analysis(self, remote_config, pipeline_name, exclusions):
|
|
@@ -141,6 +156,15 @@ class HandleRisk:
|
|
|
141
156
|
|
|
142
157
|
service = pipeline_name
|
|
143
158
|
service_list = []
|
|
159
|
+
initial_services = []
|
|
160
|
+
initial_services += [service]
|
|
161
|
+
|
|
162
|
+
match_parent = re.match(
|
|
163
|
+
risk_config["PARENT_ANALYSIS"]["REGEX_GET_PARENT"], service
|
|
164
|
+
)
|
|
165
|
+
if risk_config["PARENT_ANALYSIS"]["ENABLED"].lower() == "true" and match_parent:
|
|
166
|
+
parent_service = match_parent.group(0)
|
|
167
|
+
initial_services += [parent_service]
|
|
144
168
|
|
|
145
169
|
if risk_config["HANDLE_SERVICE_NAME"]["ENABLED"].lower() == "true":
|
|
146
170
|
service = next(
|
|
@@ -156,7 +180,7 @@ class HandleRisk:
|
|
|
156
180
|
)
|
|
157
181
|
if match_service_code:
|
|
158
182
|
service_code = match_service_code.group(0)
|
|
159
|
-
|
|
183
|
+
initial_services += [
|
|
160
184
|
service.format(service_code=service_code)
|
|
161
185
|
for service in risk_config["HANDLE_SERVICE_NAME"]["ADD_SERVICES"]
|
|
162
186
|
]
|
|
@@ -164,31 +188,33 @@ class HandleRisk:
|
|
|
164
188
|
service_code, dict_args, secret_tool, remote_config
|
|
165
189
|
)
|
|
166
190
|
service_list += self._filter_engagements(
|
|
167
|
-
engagements, service, risk_config
|
|
191
|
+
engagements, service, initial_services, risk_config
|
|
168
192
|
)
|
|
193
|
+
else:
|
|
194
|
+
for service in initial_services:
|
|
195
|
+
engagements = self.vulnerability_management.get_active_engagements(
|
|
196
|
+
service, dict_args, secret_tool, remote_config
|
|
197
|
+
)
|
|
198
|
+
for engagement in engagements:
|
|
199
|
+
if engagement.name.lower() == service.lower():
|
|
200
|
+
service_list += [engagement]
|
|
201
|
+
break
|
|
169
202
|
|
|
170
|
-
service_list += [service]
|
|
171
|
-
|
|
172
|
-
match_parent = re.match(
|
|
173
|
-
risk_config["PARENT_ANALYSIS"]["REGEX_GET_PARENT"], service
|
|
174
|
-
)
|
|
175
|
-
if risk_config["PARENT_ANALYSIS"]["ENABLED"].lower() == "true" and match_parent:
|
|
176
|
-
parent_service = match_parent.group(0)
|
|
177
|
-
service_list += [parent_service]
|
|
178
|
-
|
|
179
|
-
service_list = list(set(service_list))
|
|
180
203
|
new_service_list = self._exclude_services(
|
|
181
204
|
dict_args, pipeline_name, service_list
|
|
182
205
|
)
|
|
183
206
|
|
|
184
|
-
|
|
185
|
-
|
|
207
|
+
for engagement in new_service_list:
|
|
208
|
+
print(f"Service to analyze: {engagement.name}, URL: {engagement.vm_url}")
|
|
209
|
+
logger.info(
|
|
210
|
+
f"Service to analyze: {engagement.name}, URL: {engagement.vm_url}"
|
|
211
|
+
)
|
|
186
212
|
|
|
187
213
|
findings = []
|
|
188
214
|
exclusions = []
|
|
189
215
|
for service in new_service_list:
|
|
190
216
|
findings_list, exclusions_list = self._get_all_from_vm(
|
|
191
|
-
dict_args, secret_tool, remote_config, service
|
|
217
|
+
dict_args, secret_tool, remote_config, service.name
|
|
192
218
|
)
|
|
193
219
|
findings += findings_list
|
|
194
220
|
exclusions += exclusions_list
|
|
@@ -197,7 +223,7 @@ class HandleRisk:
|
|
|
197
223
|
dict_args,
|
|
198
224
|
findings,
|
|
199
225
|
exclusions,
|
|
200
|
-
new_service_list,
|
|
226
|
+
[service.name for service in new_service_list],
|
|
201
227
|
self.devops_platform_gateway,
|
|
202
228
|
self.print_table_gateway,
|
|
203
229
|
)
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py
CHANGED
|
@@ -263,6 +263,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
263
263
|
max_retries = config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"][
|
|
264
264
|
"MAX_RETRIES_QUERY"
|
|
265
265
|
]
|
|
266
|
+
host_dd = config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"]["HOST_DEFECT_DOJO"]
|
|
266
267
|
|
|
267
268
|
findings = self._get_findings(
|
|
268
269
|
self._get_session_manager(dict_args, secret_tool, config_tool),
|
|
@@ -273,13 +274,13 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
273
274
|
|
|
274
275
|
all_findings = list(
|
|
275
276
|
map(
|
|
276
|
-
partial(self._create_report),
|
|
277
|
+
partial(self._create_report, host_dd=host_dd),
|
|
277
278
|
findings,
|
|
278
279
|
)
|
|
279
280
|
)
|
|
280
281
|
|
|
281
282
|
all_exclusions = self._get_report_exclusions(
|
|
282
|
-
all_findings, self._format_date_to_dd_format
|
|
283
|
+
all_findings, self._format_date_to_dd_format, host_dd=host_dd
|
|
283
284
|
)
|
|
284
285
|
|
|
285
286
|
return all_findings, all_exclusions
|
|
@@ -310,7 +311,14 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
310
311
|
"active": "true",
|
|
311
312
|
}
|
|
312
313
|
|
|
313
|
-
|
|
314
|
+
engagements = Engagement.get_engagements(request_is, request_active).results
|
|
315
|
+
|
|
316
|
+
host_dd = config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"]["HOST_DEFECT_DOJO"]
|
|
317
|
+
|
|
318
|
+
for engagement in engagements:
|
|
319
|
+
engagement.vm_url = f"{host_dd}/engagement/{engagement.id}/finding/open"
|
|
320
|
+
|
|
321
|
+
return engagements
|
|
314
322
|
|
|
315
323
|
except Exception as ex:
|
|
316
324
|
raise ExceptionGettingEngagements(
|
|
@@ -326,25 +334,25 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
326
334
|
config_tool["VULNERABILITY_MANAGER"]["DEFECT_DOJO"]["HOST_DEFECT_DOJO"],
|
|
327
335
|
)
|
|
328
336
|
|
|
329
|
-
def _get_report_exclusions(self, total_findings, date_fn):
|
|
337
|
+
def _get_report_exclusions(self, total_findings, date_fn, host_dd):
|
|
330
338
|
exclusions = []
|
|
331
339
|
for finding in total_findings:
|
|
332
340
|
if finding.risk_accepted:
|
|
333
341
|
exclusions.append(
|
|
334
|
-
self.
|
|
335
|
-
finding, date_fn, "engine_risk", "Risk Accepted"
|
|
342
|
+
self._create_report_exclusion(
|
|
343
|
+
finding, date_fn, "engine_risk", "Risk Accepted", host_dd
|
|
336
344
|
)
|
|
337
345
|
)
|
|
338
346
|
elif finding.false_p:
|
|
339
347
|
exclusions.append(
|
|
340
|
-
self.
|
|
341
|
-
finding, date_fn, "engine_risk", "False Positive"
|
|
348
|
+
self._create_report_exclusion(
|
|
349
|
+
finding, date_fn, "engine_risk", "False Positive", host_dd
|
|
342
350
|
)
|
|
343
351
|
)
|
|
344
352
|
elif finding.risk_status == "Transfer Accepted":
|
|
345
353
|
exclusions.append(
|
|
346
|
-
self.
|
|
347
|
-
finding, date_fn, "engine_risk", "Transferred Finding"
|
|
354
|
+
self._create_report_exclusion(
|
|
355
|
+
finding, date_fn, "engine_risk", "Transferred Finding", host_dd
|
|
348
356
|
)
|
|
349
357
|
)
|
|
350
358
|
return exclusions
|
|
@@ -381,7 +389,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
381
389
|
logger.error("Maximum number of retries reached, aborting.")
|
|
382
390
|
raise e
|
|
383
391
|
|
|
384
|
-
def
|
|
392
|
+
def _date_reason_based(self, finding, date_fn, reason):
|
|
385
393
|
if reason == "False Positive":
|
|
386
394
|
create_date = date_fn(finding.last_status_update)
|
|
387
395
|
expired_date = date_fn(None)
|
|
@@ -393,6 +401,24 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
393
401
|
create_date = date_fn(last_accepted_risk["created"])
|
|
394
402
|
expired_date = date_fn(last_accepted_risk["expiration_date"])
|
|
395
403
|
|
|
404
|
+
return create_date, expired_date
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
def _create_exclusion(self, finding, date_fn, tool, reason):
|
|
408
|
+
create_date, expired_date = self._date_reason_based(finding, date_fn, reason)
|
|
409
|
+
|
|
410
|
+
return Exclusions(
|
|
411
|
+
id=finding.vuln_id_from_tool,
|
|
412
|
+
where=self._get_where(finding, tool),
|
|
413
|
+
create_date=create_date,
|
|
414
|
+
expired_date=expired_date,
|
|
415
|
+
severity=finding.severity,
|
|
416
|
+
reason=reason,
|
|
417
|
+
)
|
|
418
|
+
|
|
419
|
+
def _create_report_exclusion(self, finding, date_fn, tool, reason, host_dd):
|
|
420
|
+
create_date, expired_date = self._date_reason_based(finding, date_fn, reason)
|
|
421
|
+
|
|
396
422
|
return Exclusions(
|
|
397
423
|
id=finding.vuln_id_from_tool,
|
|
398
424
|
where=self._get_where(finding, tool),
|
|
@@ -400,10 +426,16 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
400
426
|
expired_date=expired_date,
|
|
401
427
|
severity=finding.severity,
|
|
402
428
|
reason=reason,
|
|
429
|
+
vm_id=str(finding.vm_id),
|
|
430
|
+
vm_id_url=f"{host_dd}/finding/{finding.vm_id}",
|
|
431
|
+
service=finding.service,
|
|
432
|
+
tags=finding.tags,
|
|
403
433
|
)
|
|
404
434
|
|
|
405
|
-
def _create_report(self, finding):
|
|
435
|
+
def _create_report(self, finding, host_dd):
|
|
406
436
|
return Report(
|
|
437
|
+
vm_id=str(finding.id),
|
|
438
|
+
vm_id_url=f"{host_dd}/finding/{finding.id}",
|
|
407
439
|
id=finding.vulnerability_ids,
|
|
408
440
|
vuln_id_from_tool=finding.vuln_id_from_tool,
|
|
409
441
|
status=finding.display_status,
|
|
@@ -449,5 +481,6 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
|
|
|
449
481
|
elif tool == "engine_risk":
|
|
450
482
|
for tag in finding.tags:
|
|
451
483
|
return self._get_where(finding, tag)
|
|
484
|
+
return finding.file_path
|
|
452
485
|
else:
|
|
453
486
|
return finding.file_path
|
|
@@ -10,7 +10,7 @@ from devsecops_engine_tools.engine_core.src.domain.model.report import (
|
|
|
10
10
|
Report,
|
|
11
11
|
)
|
|
12
12
|
from devsecops_engine_tools.engine_core.src.infrastructure.helpers.util import (
|
|
13
|
-
format_date
|
|
13
|
+
format_date,
|
|
14
14
|
)
|
|
15
15
|
from prettytable import PrettyTable, DOUBLE_BORDER
|
|
16
16
|
|
|
@@ -63,24 +63,20 @@ class PrinterPrettyTable(PrinterTableGateway):
|
|
|
63
63
|
print(sorted_table)
|
|
64
64
|
|
|
65
65
|
def print_table_report(self, report_list: "list[Report]"):
|
|
66
|
-
headers = ["Risk Score", "
|
|
66
|
+
headers = ["Risk Score", "VM ID", "Services", "Tags"]
|
|
67
67
|
table = PrettyTable(headers)
|
|
68
68
|
for report in report_list:
|
|
69
69
|
row_data = [
|
|
70
70
|
report.risk_score,
|
|
71
|
-
report.
|
|
72
|
-
|
|
73
|
-
report.tags,
|
|
74
|
-
report.where,
|
|
75
|
-
report.service
|
|
71
|
+
self._check_spaces(report.vm_id),
|
|
72
|
+
self._check_spaces(report.service),
|
|
73
|
+
", ".join(report.tags),
|
|
76
74
|
]
|
|
77
75
|
table.add_row(row_data)
|
|
78
76
|
|
|
79
77
|
sorted_table = PrettyTable()
|
|
80
78
|
sorted_table.field_names = table.field_names
|
|
81
|
-
sorted_table.add_rows(
|
|
82
|
-
sorted(table._rows, key=lambda row: row[0], reverse=True)
|
|
83
|
-
)
|
|
79
|
+
sorted_table.add_rows(sorted(table._rows, key=lambda row: row[0], reverse=True))
|
|
84
80
|
|
|
85
81
|
for column in table.field_names:
|
|
86
82
|
sorted_table.align[column] = "l"
|
|
@@ -90,9 +86,52 @@ class PrinterPrettyTable(PrinterTableGateway):
|
|
|
90
86
|
if len(sorted_table.rows) > 0:
|
|
91
87
|
print(sorted_table)
|
|
92
88
|
|
|
89
|
+
def print_table_report_exlusions(self, exclusions):
|
|
90
|
+
if exclusions:
|
|
91
|
+
headers = [
|
|
92
|
+
"VM ID",
|
|
93
|
+
"Tags",
|
|
94
|
+
"Services",
|
|
95
|
+
"Created Date",
|
|
96
|
+
"Expired Date",
|
|
97
|
+
"Reason",
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
table = PrettyTable(headers)
|
|
101
|
+
|
|
102
|
+
for exclusion in exclusions:
|
|
103
|
+
row_data = [
|
|
104
|
+
self._check_spaces(exclusion["vm_id"]),
|
|
105
|
+
", ".join(exclusion["tags"]),
|
|
106
|
+
self._check_spaces(exclusion["service"]),
|
|
107
|
+
format_date(exclusion["create_date"], "%d%m%Y", "%d/%m/%Y"),
|
|
108
|
+
(
|
|
109
|
+
format_date(exclusion["expired_date"], "%d%m%Y", "%d/%m/%Y")
|
|
110
|
+
if exclusion["expired_date"]
|
|
111
|
+
and exclusion["expired_date"] != "undefined"
|
|
112
|
+
else "NA"
|
|
113
|
+
),
|
|
114
|
+
exclusion["reason"],
|
|
115
|
+
]
|
|
116
|
+
table.add_row(row_data)
|
|
117
|
+
|
|
118
|
+
for column in table.field_names:
|
|
119
|
+
table.align[column] = "l"
|
|
120
|
+
|
|
121
|
+
table.set_style(DOUBLE_BORDER)
|
|
122
|
+
if len(table.rows) > 0:
|
|
123
|
+
print(table)
|
|
124
|
+
|
|
93
125
|
def print_table_exclusions(self, exclusions):
|
|
94
|
-
if
|
|
95
|
-
headers = [
|
|
126
|
+
if exclusions:
|
|
127
|
+
headers = [
|
|
128
|
+
"Severity",
|
|
129
|
+
"ID",
|
|
130
|
+
"Where",
|
|
131
|
+
"Create Date",
|
|
132
|
+
"Expired Date",
|
|
133
|
+
"Reason",
|
|
134
|
+
]
|
|
96
135
|
|
|
97
136
|
table = PrettyTable(headers)
|
|
98
137
|
|
|
@@ -102,7 +141,12 @@ class PrinterPrettyTable(PrinterTableGateway):
|
|
|
102
141
|
exclusion["id"],
|
|
103
142
|
exclusion["where"],
|
|
104
143
|
format_date(exclusion["create_date"], "%d%m%Y", "%d/%m/%Y"),
|
|
105
|
-
|
|
144
|
+
(
|
|
145
|
+
format_date(exclusion["expired_date"], "%d%m%Y", "%d/%m/%Y")
|
|
146
|
+
if exclusion["expired_date"]
|
|
147
|
+
and exclusion["expired_date"] != "undefined"
|
|
148
|
+
else "NA"
|
|
149
|
+
),
|
|
106
150
|
exclusion["reason"],
|
|
107
151
|
]
|
|
108
152
|
table.add_row(row_data)
|
|
@@ -113,3 +157,12 @@ class PrinterPrettyTable(PrinterTableGateway):
|
|
|
113
157
|
table.set_style(DOUBLE_BORDER)
|
|
114
158
|
if len(table.rows) > 0:
|
|
115
159
|
print(table)
|
|
160
|
+
|
|
161
|
+
def _check_spaces(self, value):
|
|
162
|
+
values = value.split()
|
|
163
|
+
new_value = ""
|
|
164
|
+
if len(values) > 1:
|
|
165
|
+
new_value = "\n".join(values)
|
|
166
|
+
else:
|
|
167
|
+
new_value = f"{values[0]}"
|
|
168
|
+
return new_value
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_rich_table/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from devsecops_engine_tools.engine_core.src.domain.model.gateway.printer_table_gateway import (
|
|
4
|
+
PrinterTableGateway,
|
|
5
|
+
)
|
|
6
|
+
from devsecops_engine_tools.engine_core.src.domain.model.finding import (
|
|
7
|
+
Finding,
|
|
8
|
+
)
|
|
9
|
+
from devsecops_engine_tools.engine_core.src.domain.model.report import (
|
|
10
|
+
Report,
|
|
11
|
+
)
|
|
12
|
+
from devsecops_engine_tools.engine_core.src.infrastructure.helpers.util import (
|
|
13
|
+
format_date,
|
|
14
|
+
)
|
|
15
|
+
from rich.console import Console
|
|
16
|
+
from rich.table import Table
|
|
17
|
+
from rich import box
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class PrinterRichTable(PrinterTableGateway):
|
|
22
|
+
def print_table_findings(self, finding_list: "list[Finding]"):
|
|
23
|
+
# To implement
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
def print_table_report(self, report_list: "list[Report]"):
|
|
27
|
+
sorted_report_list = sorted(
|
|
28
|
+
report_list, key=lambda report: report.risk_score, reverse=True
|
|
29
|
+
)
|
|
30
|
+
headers = ["Risk Score", "ID", "Tags", "Services"]
|
|
31
|
+
table = Table(
|
|
32
|
+
show_header=True, header_style="bold magenta", box=box.DOUBLE_EDGE
|
|
33
|
+
)
|
|
34
|
+
for header in headers:
|
|
35
|
+
table.add_column(header)
|
|
36
|
+
for report in sorted_report_list:
|
|
37
|
+
row_data = [
|
|
38
|
+
str(report.risk_score),
|
|
39
|
+
self._check_spaces(report.vm_id, report.vm_id_url),
|
|
40
|
+
", ".join(report.tags),
|
|
41
|
+
report.service,
|
|
42
|
+
]
|
|
43
|
+
table.add_row(*row_data)
|
|
44
|
+
console = Console()
|
|
45
|
+
console.print(table)
|
|
46
|
+
|
|
47
|
+
def print_table_exclusions(self, exclusions_list):
|
|
48
|
+
headers = []
|
|
49
|
+
if exclusions_list:
|
|
50
|
+
headers = ["ID", "Tags", "Service", "Create Date", "Expired Date", "Reason"]
|
|
51
|
+
table = Table(
|
|
52
|
+
show_header=True, header_style="bold magenta", box=box.DOUBLE_EDGE
|
|
53
|
+
)
|
|
54
|
+
for header in headers:
|
|
55
|
+
table.add_column(header)
|
|
56
|
+
for exclusion in exclusions_list:
|
|
57
|
+
row_data = [
|
|
58
|
+
self._check_spaces(exclusion["vm_id"], exclusion["vm_id_url"]),
|
|
59
|
+
", ".join(exclusion["tags"]),
|
|
60
|
+
exclusion["service"],
|
|
61
|
+
format_date(exclusion["create_date"], "%d%m%Y", "%d/%m/%Y"),
|
|
62
|
+
(
|
|
63
|
+
format_date(exclusion["expired_date"], "%d%m%Y", "%d/%m/%Y")
|
|
64
|
+
if exclusion["expired_date"]
|
|
65
|
+
and exclusion["expired_date"] != "undefined"
|
|
66
|
+
else "NA"
|
|
67
|
+
),
|
|
68
|
+
exclusion["reason"],
|
|
69
|
+
]
|
|
70
|
+
table.add_row(*row_data)
|
|
71
|
+
console = Console()
|
|
72
|
+
console.print(table)
|
|
73
|
+
|
|
74
|
+
def _check_spaces(self, value, url):
|
|
75
|
+
values = value.split()
|
|
76
|
+
urls = url.split()
|
|
77
|
+
new_value = ""
|
|
78
|
+
if len(values) > 1 or len(urls) > 1:
|
|
79
|
+
for value, url in zip(values, urls):
|
|
80
|
+
new_value += self._make_hyperlink(value, url) + " "
|
|
81
|
+
else:
|
|
82
|
+
new_value = self._make_hyperlink(values[0], urls[0])
|
|
83
|
+
return new_value
|
|
84
|
+
|
|
85
|
+
def _make_hyperlink(self, value, url):
|
|
86
|
+
return f"[link={url}]{value}[/link]"
|
|
@@ -130,14 +130,14 @@ class BreakBuild:
|
|
|
130
130
|
print(
|
|
131
131
|
self.devops_platform_gateway.message(
|
|
132
132
|
"succeeded",
|
|
133
|
-
f"Remediation
|
|
133
|
+
f"Remediation rate {remediation_rate_value}% is greater than {risk_threshold}%",
|
|
134
134
|
)
|
|
135
135
|
)
|
|
136
136
|
elif remediation_rate_value >= risk_threshold:
|
|
137
137
|
print(
|
|
138
138
|
self.devops_platform_gateway.message(
|
|
139
139
|
"warning",
|
|
140
|
-
f"Remediation
|
|
140
|
+
f"Remediation rate {remediation_rate_value}% is close to {risk_threshold}%",
|
|
141
141
|
)
|
|
142
142
|
)
|
|
143
143
|
self.warning_build = True
|
|
@@ -145,7 +145,7 @@ class BreakBuild:
|
|
|
145
145
|
print(
|
|
146
146
|
self.devops_platform_gateway.message(
|
|
147
147
|
"error",
|
|
148
|
-
f"Remediation
|
|
148
|
+
f"Remediation rate {remediation_rate_value}% is less than {risk_threshold}%",
|
|
149
149
|
)
|
|
150
150
|
)
|
|
151
151
|
self.break_build = True
|
|
@@ -162,6 +162,10 @@ class BreakBuild:
|
|
|
162
162
|
"create_date": exclusion.create_date,
|
|
163
163
|
"expired_date": exclusion.expired_date,
|
|
164
164
|
"reason": exclusion.reason,
|
|
165
|
+
"vm_id": exclusion.vm_id,
|
|
166
|
+
"vm_id_url": exclusion.vm_id_url,
|
|
167
|
+
"service": exclusion.service,
|
|
168
|
+
"tags": exclusion.tags,
|
|
165
169
|
}
|
|
166
170
|
for exclusion in exclusions
|
|
167
171
|
]
|
|
@@ -179,9 +183,15 @@ class BreakBuild:
|
|
|
179
183
|
and report.vuln_id_from_tool == exclusion.id
|
|
180
184
|
)
|
|
181
185
|
or (report.id and report.id == exclusion.id)
|
|
186
|
+
or (report.vm_id and exclusion.id in report.vm_id)
|
|
182
187
|
) and ((exclusion.where in report.where) or (exclusion.where == "all")):
|
|
183
188
|
exclude = True
|
|
184
|
-
|
|
189
|
+
exclusion_copy = copy.deepcopy(exclusion)
|
|
190
|
+
exclusion_copy.vm_id = report.vm_id
|
|
191
|
+
exclusion_copy.vm_id_url = report.vm_id_url
|
|
192
|
+
exclusion_copy.service = report.service
|
|
193
|
+
exclusion_copy.tags = report.tags
|
|
194
|
+
applied_exclusions.append(exclusion_copy)
|
|
185
195
|
break
|
|
186
196
|
if not exclude:
|
|
187
197
|
report.reason = "Remediation Rate"
|
|
@@ -214,7 +224,7 @@ class BreakBuild:
|
|
|
214
224
|
print(
|
|
215
225
|
self.devops_platform_gateway.message(
|
|
216
226
|
"error",
|
|
217
|
-
f"Report {report.
|
|
227
|
+
f"Report {report.vm_id} with tag {tag} is blacklisted and age {report.age} is above threshold {tag_age_threshold}",
|
|
218
228
|
)
|
|
219
229
|
)
|
|
220
230
|
|
|
@@ -222,7 +232,7 @@ class BreakBuild:
|
|
|
222
232
|
print(
|
|
223
233
|
self.devops_platform_gateway.message(
|
|
224
234
|
"warning",
|
|
225
|
-
f"Report {report.
|
|
235
|
+
f"Report {report.vm_id} with tag {tag} is blacklisted but age {report.age} is below threshold {tag_age_threshold}",
|
|
226
236
|
)
|
|
227
237
|
)
|
|
228
238
|
|
|
@@ -258,9 +268,7 @@ class BreakBuild:
|
|
|
258
268
|
break_build = True
|
|
259
269
|
report.reason = "Risk Score"
|
|
260
270
|
self.report_breaker.append(copy.deepcopy(report))
|
|
261
|
-
print(
|
|
262
|
-
"Below are open vulnerabilities from Vulnerability Management Platform"
|
|
263
|
-
)
|
|
271
|
+
print("Below are open findings from Vulnerability Management Platform")
|
|
264
272
|
self.printer_table_gateway.print_table_report(
|
|
265
273
|
report_list,
|
|
266
274
|
)
|
|
@@ -284,7 +292,8 @@ class BreakBuild:
|
|
|
284
292
|
else:
|
|
285
293
|
print(
|
|
286
294
|
self.devops_platform_gateway.message(
|
|
287
|
-
"succeeded",
|
|
295
|
+
"succeeded",
|
|
296
|
+
"There are no open findings from Vulnerability Management Platform",
|
|
288
297
|
)
|
|
289
298
|
)
|
|
290
299
|
|
|
@@ -295,7 +304,7 @@ class BreakBuild:
|
|
|
295
304
|
"warning", "Bellow are all findings that were excepted"
|
|
296
305
|
)
|
|
297
306
|
)
|
|
298
|
-
self.printer_table_gateway.
|
|
307
|
+
self.printer_table_gateway.print_table_report_exlusions(applied_exclusions)
|
|
299
308
|
for reason, total in Counter(
|
|
300
309
|
map(lambda x: x["reason"], applied_exclusions)
|
|
301
310
|
).items():
|
|
@@ -1,9 +1,72 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
class HandleFilters:
|
|
2
5
|
def filter(self, findings):
|
|
3
6
|
active_findings = self._get_active_findings(findings)
|
|
4
7
|
self._get_priority_vulnerability(active_findings)
|
|
5
8
|
return active_findings
|
|
6
9
|
|
|
10
|
+
def filter_duplicated(self, findings):
|
|
11
|
+
unique_findings = []
|
|
12
|
+
findings_map = {}
|
|
13
|
+
|
|
14
|
+
for finding in findings:
|
|
15
|
+
key = (finding.where, tuple(finding.id), finding.vuln_id_from_tool)
|
|
16
|
+
if key in findings_map:
|
|
17
|
+
existing_finding = findings_map[key]
|
|
18
|
+
combined_services = existing_finding.service.split() + [
|
|
19
|
+
s
|
|
20
|
+
for s in finding.service.split()
|
|
21
|
+
if s not in existing_finding.service.split()
|
|
22
|
+
]
|
|
23
|
+
combined_vm_ids = existing_finding.vm_id.split() + [
|
|
24
|
+
vm
|
|
25
|
+
for vm in finding.vm_id.split()
|
|
26
|
+
if vm not in existing_finding.vm_id.split()
|
|
27
|
+
]
|
|
28
|
+
combined_vm_id_urls = existing_finding.vm_id_url.split() + [
|
|
29
|
+
vm_url
|
|
30
|
+
for vm_url in finding.vm_id_url.split()
|
|
31
|
+
if vm_url not in existing_finding.vm_id_url.split()
|
|
32
|
+
]
|
|
33
|
+
if finding.age >= existing_finding.age:
|
|
34
|
+
new_finding = copy.deepcopy(finding)
|
|
35
|
+
new_finding.service = " ".join(combined_services)
|
|
36
|
+
new_finding.vm_id = " ".join(combined_vm_ids)
|
|
37
|
+
new_finding.vm_id_url = " ".join(combined_vm_id_urls)
|
|
38
|
+
findings_map[key] = new_finding
|
|
39
|
+
else:
|
|
40
|
+
existing_finding.service = " ".join(combined_services)
|
|
41
|
+
new_finding.vm_id = " ".join(combined_vm_ids)
|
|
42
|
+
new_finding.vm_id_url = " ".join(combined_vm_id_urls)
|
|
43
|
+
else:
|
|
44
|
+
findings_map[key] = copy.deepcopy(finding)
|
|
45
|
+
|
|
46
|
+
unique_findings = list(findings_map.values())
|
|
47
|
+
return unique_findings
|
|
48
|
+
|
|
49
|
+
def filter_tags_days(self, devops_platform_gateway, remote_config, findings):
|
|
50
|
+
tag_exclusion_days = remote_config["TAG_EXCLUSION_DAYS"]
|
|
51
|
+
filtered_findings = []
|
|
52
|
+
|
|
53
|
+
for finding in findings:
|
|
54
|
+
exclude = False
|
|
55
|
+
for tag in finding.tags:
|
|
56
|
+
if tag in tag_exclusion_days and finding.age < tag_exclusion_days[tag]:
|
|
57
|
+
exclude = True
|
|
58
|
+
print(
|
|
59
|
+
devops_platform_gateway.message(
|
|
60
|
+
"warning",
|
|
61
|
+
f"Report {finding.vm_id} with tag '{tag}' and age {finding.age} days is being excluded. It will be considered in {tag_exclusion_days[tag] - finding.age} days.",
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
break
|
|
65
|
+
if not exclude:
|
|
66
|
+
filtered_findings.append(finding)
|
|
67
|
+
|
|
68
|
+
return filtered_findings
|
|
69
|
+
|
|
7
70
|
def _get_active_findings(self, findings):
|
|
8
71
|
return list(
|
|
9
72
|
filter(
|
|
@@ -12,8 +12,6 @@ from devsecops_engine_tools.engine_risk.src.domain.usecases.get_exclusions impor
|
|
|
12
12
|
)
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
import re
|
|
16
|
-
|
|
17
15
|
from devsecops_engine_tools.engine_utilities.utils.logger_info import MyLogger
|
|
18
16
|
from devsecops_engine_tools.engine_utilities import settings
|
|
19
17
|
|
|
@@ -36,30 +34,6 @@ def init_engine_risk(
|
|
|
36
34
|
dict_args["remote_config_repo"], "engine_risk/Exclusions.json"
|
|
37
35
|
)
|
|
38
36
|
|
|
39
|
-
return process_findings(
|
|
40
|
-
findings,
|
|
41
|
-
vm_exclusions,
|
|
42
|
-
dict_args,
|
|
43
|
-
services,
|
|
44
|
-
risk_exclusions,
|
|
45
|
-
remote_config,
|
|
46
|
-
add_epss_gateway,
|
|
47
|
-
devops_platform_gateway,
|
|
48
|
-
print_table_gateway,
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def process_findings(
|
|
53
|
-
findings,
|
|
54
|
-
vm_exclusions,
|
|
55
|
-
dict_args,
|
|
56
|
-
services,
|
|
57
|
-
risk_exclusions,
|
|
58
|
-
remote_config,
|
|
59
|
-
add_epss_gateway,
|
|
60
|
-
devops_platform_gateway,
|
|
61
|
-
print_table_gateway,
|
|
62
|
-
):
|
|
63
37
|
if not findings:
|
|
64
38
|
print("No findings found in Vulnerability Management Platform")
|
|
65
39
|
logger.info("No findings found in Vulnerability Management Platform")
|
|
@@ -67,33 +41,16 @@ def process_findings(
|
|
|
67
41
|
|
|
68
42
|
handle_filters = HandleFilters()
|
|
69
43
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
remote_config,
|
|
77
|
-
risk_exclusions,
|
|
78
|
-
services,
|
|
79
|
-
add_epss_gateway,
|
|
80
|
-
print_table_gateway,
|
|
44
|
+
active_findings = handle_filters.filter(findings)
|
|
45
|
+
|
|
46
|
+
unique_findings = handle_filters.filter_duplicated(active_findings)
|
|
47
|
+
|
|
48
|
+
filtered_findings = handle_filters.filter_tags_days(
|
|
49
|
+
devops_platform_gateway, remote_config, unique_findings
|
|
81
50
|
)
|
|
82
51
|
|
|
52
|
+
data_added = AddData(add_epss_gateway, filtered_findings).process()
|
|
83
53
|
|
|
84
|
-
def process_active_findings(
|
|
85
|
-
active_findings,
|
|
86
|
-
total_findings,
|
|
87
|
-
vm_exclusions,
|
|
88
|
-
devops_platform_gateway,
|
|
89
|
-
dict_args,
|
|
90
|
-
remote_config,
|
|
91
|
-
risk_exclusions,
|
|
92
|
-
services,
|
|
93
|
-
add_epss_gateway,
|
|
94
|
-
print_table_gateway,
|
|
95
|
-
):
|
|
96
|
-
data_added = AddData(add_epss_gateway, active_findings).process()
|
|
97
54
|
get_exclusions = GetExclusions(
|
|
98
55
|
devops_platform_gateway,
|
|
99
56
|
dict_args,
|
|
@@ -103,6 +60,7 @@ def process_active_findings(
|
|
|
103
60
|
services,
|
|
104
61
|
)
|
|
105
62
|
exclusions = get_exclusions.process()
|
|
63
|
+
|
|
106
64
|
break_build = BreakBuild(
|
|
107
65
|
devops_platform_gateway,
|
|
108
66
|
print_table_gateway,
|
|
@@ -110,7 +68,7 @@ def process_active_findings(
|
|
|
110
68
|
exclusions,
|
|
111
69
|
vm_exclusions,
|
|
112
70
|
data_added,
|
|
113
|
-
|
|
71
|
+
findings,
|
|
114
72
|
)
|
|
115
73
|
|
|
116
74
|
return break_build.process()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
version = '1.
|
|
1
|
+
version = '1.17.0'
|
{devsecops_engine_tools-1.16.0.dist-info → devsecops_engine_tools-1.17.0.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: devsecops-engine-tools
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.17.0
|
|
4
4
|
Summary: Tool for DevSecOps strategy
|
|
5
5
|
Home-page: https://github.com/bancolombia/devsecops-engine-tools
|
|
6
6
|
Author: Bancolombia DevSecOps Team
|
|
@@ -25,6 +25,7 @@ Requires-Dist: distro==1.9.0
|
|
|
25
25
|
Requires-Dist: boto3==1.34.157
|
|
26
26
|
Requires-Dist: docker==7.1.0
|
|
27
27
|
Requires-Dist: setuptools==72.1.0
|
|
28
|
+
Requires-Dist: rich==13.9.4
|
|
28
29
|
|
|
29
30
|
# DevSecOps Engine Tools
|
|
30
31
|
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
devsecops_engine_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
devsecops_engine_tools/version.py,sha256=
|
|
2
|
+
devsecops_engine_tools/version.py,sha256=MzQoSPABd45fuiVSL0Hxyz3S5B7-9HeNc1g4a1oKlOY,19
|
|
3
3
|
devsecops_engine_tools/engine_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
devsecops_engine_tools/engine_core/src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
devsecops_engine_tools/engine_core/src/applications/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
devsecops_engine_tools/engine_core/src/applications/runner_engine_core.py,sha256=
|
|
6
|
+
devsecops_engine_tools/engine_core/src/applications/runner_engine_core.py,sha256=3IvzG7IfQFs8gxsv4Xo5722hV3jG6g0g4JWFq74i2iM,7209
|
|
7
7
|
devsecops_engine_tools/engine_core/src/deployment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
devsecops_engine_tools/engine_core/src/deployment/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
devsecops_engine_tools/engine_core/src/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
devsecops_engine_tools/engine_core/src/domain/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
11
|
devsecops_engine_tools/engine_core/src/domain/model/customs_exceptions.py,sha256=YLeOj4O7kNsUx8RD6pwBQdFLYbkm7Eh-F-ohZ3jFGbs,599
|
|
12
|
-
devsecops_engine_tools/engine_core/src/domain/model/exclusions.py,sha256=
|
|
12
|
+
devsecops_engine_tools/engine_core/src/domain/model/exclusions.py,sha256=W9DXUWI7rGJWRHEulnUY5ybdJK2wknG4zY7CbTtSyfc,689
|
|
13
13
|
devsecops_engine_tools/engine_core/src/domain/model/finding.py,sha256=MntDksQuPt1L-1Ww3nK7NbMLfVwRjxPGCN_oHYXbbWk,383
|
|
14
14
|
devsecops_engine_tools/engine_core/src/domain/model/input_core.py,sha256=hc1WMzCwsGxnrlvvk84S5iNYJRDQWbaQP9MwR3N7tVM,422
|
|
15
15
|
devsecops_engine_tools/engine_core/src/domain/model/level_compliance.py,sha256=ntn_UWqHc6sT5g_LozBdjdewTQxFsp7Kt8M0xqw-k_o,98
|
|
16
16
|
devsecops_engine_tools/engine_core/src/domain/model/level_vulnerability.py,sha256=0sySEnFNkS2Y8uF5GUVAYehXw-i2OglUClkVobnSTPc,257
|
|
17
|
-
devsecops_engine_tools/engine_core/src/domain/model/report.py,sha256=
|
|
17
|
+
devsecops_engine_tools/engine_core/src/domain/model/report.py,sha256=6ByyjXmUbowWbZIkn3qfL-QyhkyCDzdTCdRj-I7wTXA,1870
|
|
18
18
|
devsecops_engine_tools/engine_core/src/domain/model/threshold.py,sha256=TCBECuvoC3-9g8vg3iKWGIixssNecP0iUaZ9Qzv0n7w,596
|
|
19
19
|
devsecops_engine_tools/engine_core/src/domain/model/vulnerability_management.py,sha256=5RcMHpeqznrTOpkjLuqekA_Bqf2Qr-w6OZ5Eoi3b-bs,465
|
|
20
20
|
devsecops_engine_tools/engine_core/src/domain/model/gateway/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -25,7 +25,7 @@ devsecops_engine_tools/engine_core/src/domain/model/gateway/secrets_manager_gate
|
|
|
25
25
|
devsecops_engine_tools/engine_core/src/domain/model/gateway/vulnerability_management_gateway.py,sha256=dT2YDlWJ4Zvny_5uCTtxBojw4i77UOgGbs8p2jlRo74,1137
|
|
26
26
|
devsecops_engine_tools/engine_core/src/domain/usecases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
27
|
devsecops_engine_tools/engine_core/src/domain/usecases/break_build.py,sha256=0JK4U5LGxzrLVZOw68j1PMxmLTDPru7Kts_-RtAG0jA,15965
|
|
28
|
-
devsecops_engine_tools/engine_core/src/domain/usecases/handle_risk.py,sha256=
|
|
28
|
+
devsecops_engine_tools/engine_core/src/domain/usecases/handle_risk.py,sha256=9Qhh1n8rUCYugEMJ72Mlk3R9SH_wYEbLdGlA6NetBrQ,9269
|
|
29
29
|
devsecops_engine_tools/engine_core/src/domain/usecases/handle_scan.py,sha256=Li0NDwHwj_g2iM4tKF3wyKqXWYXspTThzKxkSma3S6E,8912
|
|
30
30
|
devsecops_engine_tools/engine_core/src/domain/usecases/metrics_manager.py,sha256=Xi0iNnPrFgqd2cBdAA5E_tgouhxs-BTo016aolnGgv8,2413
|
|
31
31
|
devsecops_engine_tools/engine_core/src/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -36,11 +36,13 @@ devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/aws/secret
|
|
|
36
36
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/azure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
37
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/azure/azure_devops.py,sha256=blI4ZrquRE4y6DJ7N2YRx1nL0wrAXvdpx0fLSUf5qwA,4831
|
|
38
38
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
-
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py,sha256=
|
|
39
|
+
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py,sha256=A_xCCj7Gs5-LAJY8bs1p_nViTI_sdtegmO3_cdPjh-Q,19580
|
|
40
40
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/github/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
41
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/github/github_actions.py,sha256=pxlgjhX4-Dssn-XHKK8AdCOj6Ry6VcQtoDf5q8CxTks,3731
|
|
42
42
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_pretty_table/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
|
-
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_pretty_table/printer_pretty_table.py,sha256=
|
|
43
|
+
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_pretty_table/printer_pretty_table.py,sha256=P0oavy_3AMbuRx5kPPiM2_LopVXqHK4Hz4Lb2UNfr-4,5369
|
|
44
|
+
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_rich_table/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
|
+
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_rich_table/printer_rich_table.py,sha256=LPr3xSv0I7ENEdu1xj8ve5PXzpUohs7hbQvHjDSaUuE,3028
|
|
44
46
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/runtime_local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
47
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/runtime_local/runtime_local.py,sha256=qKINENZGbfV8XFF7fzUK6grQ5Jx7Nwv9xOqjjKlXp3o,2475
|
|
46
48
|
devsecops_engine_tools/engine_core/src/infrastructure/entry_points/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -72,15 +74,15 @@ devsecops_engine_tools/engine_risk/src/domain/model/gateways/__init__.py,sha256=
|
|
|
72
74
|
devsecops_engine_tools/engine_risk/src/domain/model/gateways/add_epss_gateway.py,sha256=cTm4QSxiaUt7ETCdXWZxKEus8pmEDA3e9k5b39SLDDE,178
|
|
73
75
|
devsecops_engine_tools/engine_risk/src/domain/usecases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
76
|
devsecops_engine_tools/engine_risk/src/domain/usecases/add_data.py,sha256=4wqDj-q7hJfJscvrbMDcy7tONqxdxl-CSl_TWTRUGKA,402
|
|
75
|
-
devsecops_engine_tools/engine_risk/src/domain/usecases/break_build.py,sha256=
|
|
77
|
+
devsecops_engine_tools/engine_risk/src/domain/usecases/break_build.py,sha256=TSZTXR8raKA1906dFl-Cv3J711iGUcBQmx82Jw6mF_M,11847
|
|
76
78
|
devsecops_engine_tools/engine_risk/src/domain/usecases/get_exclusions.py,sha256=o4vMpmgt5q1BsaWpGZWdCHPVs1CFyj-P3TrgOSEBcqM,2327
|
|
77
|
-
devsecops_engine_tools/engine_risk/src/domain/usecases/handle_filters.py,sha256=
|
|
79
|
+
devsecops_engine_tools/engine_risk/src/domain/usecases/handle_filters.py,sha256=1yJKPzh64gu67g_pLyr7V8Ahzs3KK8tncigPzKWMX7Q,3533
|
|
78
80
|
devsecops_engine_tools/engine_risk/src/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
79
81
|
devsecops_engine_tools/engine_risk/src/infrastructure/driven_adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
80
82
|
devsecops_engine_tools/engine_risk/src/infrastructure/driven_adapters/first_csv/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
81
83
|
devsecops_engine_tools/engine_risk/src/infrastructure/driven_adapters/first_csv/first_epss_csv.py,sha256=pWaRmIwVyiB5mlmWySHIx-DUgN9vtKQc-MqyRNVlTJo,2150
|
|
82
84
|
devsecops_engine_tools/engine_risk/src/infrastructure/entry_points/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
83
|
-
devsecops_engine_tools/engine_risk/src/infrastructure/entry_points/entry_point_risk.py,sha256=
|
|
85
|
+
devsecops_engine_tools/engine_risk/src/infrastructure/entry_points/entry_point_risk.py,sha256=DQe1yUd5p83zecH53jKrsnS-JV2ZaN7YvdtQLwzEx0A,2073
|
|
84
86
|
devsecops_engine_tools/engine_risk/src/infrastructure/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
85
87
|
devsecops_engine_tools/engine_sast/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
86
88
|
devsecops_engine_tools/engine_sast/engine_code/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -231,7 +233,7 @@ devsecops_engine_tools/engine_utilities/defect_dojo/applications/product.py,sha2
|
|
|
231
233
|
devsecops_engine_tools/engine_utilities/defect_dojo/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
232
234
|
devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
233
235
|
devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/cmdb.py,sha256=7EAzKzBJaDqP4Q57cyu_nCpl9WqcTZFjXydkYCh8h-k,320
|
|
234
|
-
devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/engagement.py,sha256=
|
|
236
|
+
devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/engagement.py,sha256=MXb7c526tz0zSDS8xGPC5IjTMF9g9qtzcEKLyfcY89c,1393
|
|
235
237
|
devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/finding.py,sha256=0Xj7BOlC30LCdBjIkviB2QmmdSj0GlDvT1-TbnaT8nE,3201
|
|
236
238
|
devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/product.py,sha256=KL5ue6icA8HH1xKkmAJzElAat3OOYU3_lt3xuNfo7Mc,1272
|
|
237
239
|
devsecops_engine_tools/engine_utilities/defect_dojo/domain/models/product_list.py,sha256=yFo8eYOGJiJMkU5pGpW0r1o5uVaNP5iA80-5w_MyWxU,664
|
|
@@ -305,8 +307,8 @@ devsecops_engine_tools/engine_utilities/utils/name_conversion.py,sha256=ADJrRGax
|
|
|
305
307
|
devsecops_engine_tools/engine_utilities/utils/printers.py,sha256=amYAr9YQfYgR6jK9a2l26z3oovFPQ3FAKmhq6BKhEBA,623
|
|
306
308
|
devsecops_engine_tools/engine_utilities/utils/session_manager.py,sha256=yNtlT-8Legz1sHbGPH8LNYjL-LgDUE0zXG2rYjiab7U,290
|
|
307
309
|
devsecops_engine_tools/engine_utilities/utils/utils.py,sha256=r_mng-OVWeqQyy6yIFsCeJrvH81VUPI3o1zdJO0JS0I,397
|
|
308
|
-
devsecops_engine_tools-1.
|
|
309
|
-
devsecops_engine_tools-1.
|
|
310
|
-
devsecops_engine_tools-1.
|
|
311
|
-
devsecops_engine_tools-1.
|
|
312
|
-
devsecops_engine_tools-1.
|
|
310
|
+
devsecops_engine_tools-1.17.0.dist-info/METADATA,sha256=f-E-4AUfAQIKU1HUjIVKBd_d5X4IcETjUTl1BFIOlKA,10895
|
|
311
|
+
devsecops_engine_tools-1.17.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
|
312
|
+
devsecops_engine_tools-1.17.0.dist-info/entry_points.txt,sha256=MHCTFFs9bdNKo6YcWCcBW2_8X6yTisgLOlmVx-V8Rxc,276
|
|
313
|
+
devsecops_engine_tools-1.17.0.dist-info/top_level.txt,sha256=ge6y0X_xBAU1aG3EMWFtl9djbVyg5BxuSp2r2Lg6EQU,23
|
|
314
|
+
devsecops_engine_tools-1.17.0.dist-info/RECORD,,
|
|
File without changes
|
{devsecops_engine_tools-1.16.0.dist-info → devsecops_engine_tools-1.17.0.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{devsecops_engine_tools-1.16.0.dist-info → devsecops_engine_tools-1.17.0.dist-info}/top_level.txt
RENAMED
|
File without changes
|