devsecops-engine-tools 1.87.1__py3-none-any.whl → 1.88.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_sca/engine_container/src/domain/model/gateways/tool_gateway.py +1 -1
- devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/container_sca_scan.py +67 -39
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_cloud_manager_scan.py +5 -1
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/trivy_manager_scan.py +15 -7
- devsecops_engine_tools/version.py +1 -1
- {devsecops_engine_tools-1.87.1.dist-info → devsecops_engine_tools-1.88.0.dist-info}/METADATA +1 -1
- {devsecops_engine_tools-1.87.1.dist-info → devsecops_engine_tools-1.88.0.dist-info}/RECORD +10 -10
- {devsecops_engine_tools-1.87.1.dist-info → devsecops_engine_tools-1.88.0.dist-info}/WHEEL +0 -0
- {devsecops_engine_tools-1.87.1.dist-info → devsecops_engine_tools-1.88.0.dist-info}/entry_points.txt +0 -0
- {devsecops_engine_tools-1.87.1.dist-info → devsecops_engine_tools-1.88.0.dist-info}/top_level.txt +0 -0
devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/tool_gateway.py
CHANGED
|
@@ -3,5 +3,5 @@ from abc import ABCMeta, abstractmethod
|
|
|
3
3
|
|
|
4
4
|
class ToolGateway(metaclass=ABCMeta):
|
|
5
5
|
@abstractmethod
|
|
6
|
-
def run_tool_container_sca(self, dict_args, secret_tool, token_engine_container, scan_image, release, base_image, exclusions, generate_sbom):
|
|
6
|
+
def run_tool_container_sca(self, dict_args, secret_tool, token_engine_container, scan_image, release, base_image, exclusions, generate_sbom, is_compressed_file=False):
|
|
7
7
|
"run tool container sca"
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/container_sca_scan.py
CHANGED
|
@@ -38,6 +38,13 @@ class ContainerScaScan:
|
|
|
38
38
|
self.pipeline_name = pipeline_name
|
|
39
39
|
self.context = context
|
|
40
40
|
|
|
41
|
+
def _is_compressed_file(self, image_to_scan):
|
|
42
|
+
"""Check if the input is a compressed file (tar, tar.gz, etc.)"""
|
|
43
|
+
return any(
|
|
44
|
+
image_to_scan.lower().endswith(ext)
|
|
45
|
+
for ext in ['.tar', '.tar.gz', '.tgz', '.tar.bz2', '.tar.xz']
|
|
46
|
+
)
|
|
47
|
+
|
|
41
48
|
def process(self):
|
|
42
49
|
"""
|
|
43
50
|
Process SCA scanning.
|
|
@@ -47,51 +54,72 @@ class ContainerScaScan:
|
|
|
47
54
|
"""
|
|
48
55
|
base_image = None
|
|
49
56
|
image_scanned = None
|
|
50
|
-
matching_image = self._get_image(self.image_to_scan)
|
|
51
|
-
if self.remote_config["GET_IMAGE_BASE"]["ENABLED"]:
|
|
52
|
-
base_image = self._get_base_image(matching_image)
|
|
53
|
-
if self.remote_config["VALIDATE_BASE_IMAGE_DATE"][
|
|
54
|
-
"ENABLED"
|
|
55
|
-
] and not self.exclusions.get(self.pipeline_name, {}).get(
|
|
56
|
-
"VALIDATE_BASE_IMAGE_DATE"
|
|
57
|
-
):
|
|
58
|
-
self._validate_base_image_date(
|
|
59
|
-
matching_image,
|
|
60
|
-
self.remote_config["VALIDATE_BASE_IMAGE_DATE"]["REFERENCE_IMAGE_DATE"],
|
|
61
|
-
)
|
|
62
|
-
if self.remote_config["BLACK_LIST_BASE_IMAGE"][
|
|
63
|
-
"ENABLED"
|
|
64
|
-
] and not self.exclusions.get(self.pipeline_name, {}).get(
|
|
65
|
-
"BLACK_LIST_BASE_IMAGE"
|
|
66
|
-
):
|
|
67
|
-
self._validate_black_list_base_image(
|
|
68
|
-
base_image, self.remote_config["BLACK_LIST_BASE_IMAGE"]["BLACK_LIST"]
|
|
69
|
-
)
|
|
70
|
-
|
|
71
57
|
sbom_components = None
|
|
58
|
+
|
|
59
|
+
is_compressed_file = self._is_compressed_file(self.image_to_scan)
|
|
60
|
+
|
|
61
|
+
if is_compressed_file:
|
|
62
|
+
if not os.path.exists(self.image_to_scan):
|
|
63
|
+
print(f"Compressed file not found: {self.image_to_scan}. Tool skipped.")
|
|
64
|
+
return image_scanned, base_image, sbom_components
|
|
65
|
+
|
|
66
|
+
matching_image = None
|
|
67
|
+
image_name = self.image_to_scan
|
|
68
|
+
print(f"Processing compressed file: {image_name}")
|
|
69
|
+
else:
|
|
70
|
+
matching_image = self._get_image(self.image_to_scan)
|
|
71
|
+
if not matching_image:
|
|
72
|
+
print(f"'Not image found for {self.image_to_scan}'. Tool skipped.")
|
|
73
|
+
return image_scanned, base_image, sbom_components
|
|
74
|
+
|
|
75
|
+
image_name = matching_image.tags[0]
|
|
76
|
+
|
|
77
|
+
if self.remote_config["GET_IMAGE_BASE"]["ENABLED"]:
|
|
78
|
+
base_image = self._get_base_image(matching_image)
|
|
79
|
+
if self.remote_config["VALIDATE_BASE_IMAGE_DATE"][
|
|
80
|
+
"ENABLED"
|
|
81
|
+
] and not self.exclusions.get(self.pipeline_name, {}).get(
|
|
82
|
+
"VALIDATE_BASE_IMAGE_DATE"
|
|
83
|
+
):
|
|
84
|
+
self._validate_base_image_date(
|
|
85
|
+
matching_image,
|
|
86
|
+
self.remote_config["VALIDATE_BASE_IMAGE_DATE"]["REFERENCE_IMAGE_DATE"],
|
|
87
|
+
)
|
|
88
|
+
if self.remote_config["BLACK_LIST_BASE_IMAGE"][
|
|
89
|
+
"ENABLED"
|
|
90
|
+
] and not self.exclusions.get(self.pipeline_name, {}).get(
|
|
91
|
+
"BLACK_LIST_BASE_IMAGE"
|
|
92
|
+
):
|
|
93
|
+
self._validate_black_list_base_image(
|
|
94
|
+
base_image, self.remote_config["BLACK_LIST_BASE_IMAGE"]["BLACK_LIST"]
|
|
95
|
+
)
|
|
96
|
+
|
|
72
97
|
generate_sbom = self.remote_config["SBOM"]["ENABLED"] and any(
|
|
73
98
|
branch in str(self.branch)
|
|
74
99
|
for branch in self.remote_config["SBOM"]["BRANCH_FILTER"]
|
|
75
100
|
)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
101
|
+
|
|
102
|
+
result_file = image_name.replace("/", "_").replace(".", "_") + "_scan_result.json"
|
|
103
|
+
|
|
104
|
+
if not is_compressed_file and image_name in self._get_images_already_scanned():
|
|
105
|
+
print(f"The image {image_name} has already been scanned previously.")
|
|
106
|
+
return image_scanned, base_image, sbom_components
|
|
107
|
+
|
|
108
|
+
image_scanned, sbom_components = self.tool_run.run_tool_container_sca(
|
|
109
|
+
self.remote_config,
|
|
110
|
+
self.secret_tool,
|
|
111
|
+
self.token_engine_container,
|
|
112
|
+
image_name,
|
|
113
|
+
result_file,
|
|
114
|
+
base_image,
|
|
115
|
+
self.exclusions,
|
|
116
|
+
generate_sbom,
|
|
117
|
+
is_compressed_file,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
if not is_compressed_file:
|
|
92
121
|
self._set_image_scanned(image_name)
|
|
93
|
-
|
|
94
|
-
print(f"'Not image found for {self.image_to_scan}'. Tool skipped.")
|
|
122
|
+
|
|
95
123
|
return image_scanned, base_image, sbom_components
|
|
96
124
|
|
|
97
125
|
def deseralizator(self, image_scanned):
|
|
@@ -171,8 +171,12 @@ class PrismaCloudManagerScan(ToolGateway):
|
|
|
171
171
|
raise ValueError("The string is not properly formatted. Make sure it contains a ':'.")
|
|
172
172
|
|
|
173
173
|
def run_tool_container_sca(
|
|
174
|
-
self, remoteconfig, secret_tool, token_engine_container, image_name, result_file, base_image, exclusions, generate_sbom
|
|
174
|
+
self, remoteconfig, secret_tool, token_engine_container, image_name, result_file, base_image, exclusions, generate_sbom, is_compressed_file=False
|
|
175
175
|
):
|
|
176
|
+
if is_compressed_file:
|
|
177
|
+
logger.warning("Prisma Cloud does not support compressed file scanning. Skipping.")
|
|
178
|
+
return "", None
|
|
179
|
+
|
|
176
180
|
prisma_key = (
|
|
177
181
|
f"{secret_tool['access_prisma']}:{secret_tool['token_prisma']}" if secret_tool else token_engine_container
|
|
178
182
|
)
|
|
@@ -62,7 +62,7 @@ class TrivyScan(ToolGateway):
|
|
|
62
62
|
except Exception as e:
|
|
63
63
|
logger.error(f"Error installing trivy: {e}")
|
|
64
64
|
|
|
65
|
-
def scan_image(self, prefix, image_name, result_file, base_image):
|
|
65
|
+
def scan_image(self, prefix, image_name, result_file, base_image, is_compressed_file=False):
|
|
66
66
|
command = [
|
|
67
67
|
prefix,
|
|
68
68
|
"--scanners",
|
|
@@ -72,7 +72,12 @@ class TrivyScan(ToolGateway):
|
|
|
72
72
|
"-o",
|
|
73
73
|
result_file,
|
|
74
74
|
]
|
|
75
|
-
|
|
75
|
+
|
|
76
|
+
if is_compressed_file:
|
|
77
|
+
command.extend(["--quiet", "image", "--input", image_name])
|
|
78
|
+
else:
|
|
79
|
+
command.extend(["--quiet", "image", image_name])
|
|
80
|
+
|
|
76
81
|
try:
|
|
77
82
|
subprocess.run(
|
|
78
83
|
command,
|
|
@@ -88,7 +93,7 @@ class TrivyScan(ToolGateway):
|
|
|
88
93
|
except Exception as e:
|
|
89
94
|
logger.error(f"Error during image scan of {image_name}: {e}")
|
|
90
95
|
|
|
91
|
-
def _generate_sbom(self, prefix, image_name, remoteconfig):
|
|
96
|
+
def _generate_sbom(self, prefix, image_name, remoteconfig, is_compressed_file=False):
|
|
92
97
|
result_sbom = f"{image_name.replace('/', '_')}_SBOM.json"
|
|
93
98
|
command = [
|
|
94
99
|
prefix,
|
|
@@ -98,7 +103,10 @@ class TrivyScan(ToolGateway):
|
|
|
98
103
|
"--output",
|
|
99
104
|
result_sbom
|
|
100
105
|
]
|
|
101
|
-
|
|
106
|
+
if is_compressed_file:
|
|
107
|
+
command.extend(["--quiet", "--input", image_name])
|
|
108
|
+
else:
|
|
109
|
+
command.extend(["--quiet", image_name])
|
|
102
110
|
try:
|
|
103
111
|
subprocess.run(
|
|
104
112
|
command,
|
|
@@ -114,7 +122,7 @@ class TrivyScan(ToolGateway):
|
|
|
114
122
|
except Exception as e:
|
|
115
123
|
logger.error(f"Error generating SBOM: {e}")
|
|
116
124
|
|
|
117
|
-
def run_tool_container_sca(self, remoteconfig, secret_tool, token_engine_container, image_name, result_file, base_image, exclusions, generate_sbom):
|
|
125
|
+
def run_tool_container_sca(self, remoteconfig, secret_tool, token_engine_container, image_name, result_file, base_image, exclusions, generate_sbom, is_compressed_file=False):
|
|
118
126
|
trivy_version = remoteconfig["TRIVY"]["TRIVY_VERSION"]
|
|
119
127
|
os_platform = platform.system()
|
|
120
128
|
arch_platform = platform.architecture()[0]
|
|
@@ -136,9 +144,9 @@ class TrivyScan(ToolGateway):
|
|
|
136
144
|
return None
|
|
137
145
|
|
|
138
146
|
image_scanned = (
|
|
139
|
-
self.scan_image(command_prefix, image_name, result_file, base_image)
|
|
147
|
+
self.scan_image(command_prefix, image_name, result_file, base_image, is_compressed_file)
|
|
140
148
|
)
|
|
141
149
|
if generate_sbom:
|
|
142
|
-
sbom_components = self._generate_sbom(command_prefix, image_name, remoteconfig)
|
|
150
|
+
sbom_components = self._generate_sbom(command_prefix, image_name, remoteconfig, is_compressed_file)
|
|
143
151
|
|
|
144
152
|
return image_scanned, sbom_components
|
|
@@ -1 +1 @@
|
|
|
1
|
-
version = '1.
|
|
1
|
+
version = '1.88.0'
|
|
@@ -1,5 +1,5 @@
|
|
|
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=yr2qJOoKyxSLorYEVz0SVgwOXwSnEc6XRZxWktmrRAs,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
|
|
@@ -201,9 +201,9 @@ devsecops_engine_tools/engine_sca/engine_container/src/domain/model/context_cont
|
|
|
201
201
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
202
202
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/deserealizator_gateway.py,sha256=AVPZvwwhV-Vns7cM58vHzd4_no2xSdzHUKiI6-2lpNM,576
|
|
203
203
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/images_gateway.py,sha256=-bsTPQW6m6aVJ1NsWC0gQnmhsYMhsNL7HpC0ONvjJjU,648
|
|
204
|
-
devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/tool_gateway.py,sha256=
|
|
204
|
+
devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/tool_gateway.py,sha256=HdBGR0QnSCiDlj9bKk6Q55jr9tc65bXbVYIqbWBCy0s,312
|
|
205
205
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
206
|
-
devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/container_sca_scan.py,sha256=
|
|
206
|
+
devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/container_sca_scan.py,sha256=nCdt4tuh9cfMa6PNIun7GNiS5AOBkmDENlHCLB5rJ7w,7232
|
|
207
207
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/handle_remote_config_patterns.py,sha256=4wgBTQSDE-C5v01C3Vxzeq0DJKZUSqQ5TVLG7yPZPKs,926
|
|
208
208
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/set_input_core.py,sha256=A5PpY0li7Pil2vPMpOHi0kkliqCxGbpQyBcB9VKyx5c,2904
|
|
209
209
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -211,11 +211,11 @@ devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_ada
|
|
|
211
211
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/docker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
212
212
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/docker/docker_images.py,sha256=VvkRP1knlRGUa6PE2zKTeByQuJVW27PF2FJ0zRy2TDA,6371
|
|
213
213
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
214
|
-
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_cloud_manager_scan.py,sha256=
|
|
214
|
+
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_cloud_manager_scan.py,sha256=Un0YmZeGh3LpOHiq6872lphD15cf02R9hwBUiHVuhCM,7848
|
|
215
215
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_deserialize_output.py,sha256=Eb7eRLyKQizPvaeX9uH8E1wxIKXCaAyNKUpmldw_iL8,2680
|
|
216
216
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
217
217
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/trivy_deserialize_output.py,sha256=f74mfDkzA7MD7QsaG-LDbcc2fX9nMvHHp-AkrcBg-h0,5294
|
|
218
|
-
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/trivy_manager_scan.py,sha256=
|
|
218
|
+
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/trivy_manager_scan.py,sha256=pX5jGm218sLJDjFDW-KPU5hZCkxtvc4dj_heSrzsReQ,5478
|
|
219
219
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/entry_points/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
220
220
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/entry_points/entry_point_tool.py,sha256=MCBVnUxfjnax2stjn9ByM0Hy9LQ9vAMK9GZkOk3ex9M,3077
|
|
221
221
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -350,8 +350,8 @@ devsecops_engine_tools/engine_utilities/utils/name_conversion.py,sha256=ADJrRGax
|
|
|
350
350
|
devsecops_engine_tools/engine_utilities/utils/printers.py,sha256=amYAr9YQfYgR6jK9a2l26z3oovFPQ3FAKmhq6BKhEBA,623
|
|
351
351
|
devsecops_engine_tools/engine_utilities/utils/session_manager.py,sha256=Z0fdhB3r-dxU0nGSD9zW_B4r2Qol1rUnUCkhFR0U-HQ,487
|
|
352
352
|
devsecops_engine_tools/engine_utilities/utils/utils.py,sha256=HCjS900TBoNcHrC4LaiP-Kf9frVdtagF130qOUgnO2M,6757
|
|
353
|
-
devsecops_engine_tools-1.
|
|
354
|
-
devsecops_engine_tools-1.
|
|
355
|
-
devsecops_engine_tools-1.
|
|
356
|
-
devsecops_engine_tools-1.
|
|
357
|
-
devsecops_engine_tools-1.
|
|
353
|
+
devsecops_engine_tools-1.88.0.dist-info/METADATA,sha256=zWFG8Ln2FSoyUV47_Q4bGdNlNlS3_idnYGKJ9-cXhPc,12093
|
|
354
|
+
devsecops_engine_tools-1.88.0.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
|
|
355
|
+
devsecops_engine_tools-1.88.0.dist-info/entry_points.txt,sha256=MHCTFFs9bdNKo6YcWCcBW2_8X6yTisgLOlmVx-V8Rxc,276
|
|
356
|
+
devsecops_engine_tools-1.88.0.dist-info/top_level.txt,sha256=ge6y0X_xBAU1aG3EMWFtl9djbVyg5BxuSp2r2Lg6EQU,23
|
|
357
|
+
devsecops_engine_tools-1.88.0.dist-info/RECORD,,
|
|
File without changes
|
{devsecops_engine_tools-1.87.1.dist-info → devsecops_engine_tools-1.88.0.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{devsecops_engine_tools-1.87.1.dist-info → devsecops_engine_tools-1.88.0.dist-info}/top_level.txt
RENAMED
|
File without changes
|