devsecops-engine-tools 1.42.3__py3-none-any.whl → 1.43.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/infrastructure/driven_adapters/github/github_actions.py +1 -1
- devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/images_gateway.py +4 -0
- devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/container_sca_scan.py +29 -5
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/docker/docker_images.py +75 -10
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/entry_points/entry_point_tool.py +2 -1
- devsecops_engine_tools/version.py +1 -1
- {devsecops_engine_tools-1.42.3.dist-info → devsecops_engine_tools-1.43.0.dist-info}/METADATA +1 -1
- {devsecops_engine_tools-1.42.3.dist-info → devsecops_engine_tools-1.43.0.dist-info}/RECORD +11 -11
- {devsecops_engine_tools-1.42.3.dist-info → devsecops_engine_tools-1.43.0.dist-info}/WHEEL +0 -0
- {devsecops_engine_tools-1.42.3.dist-info → devsecops_engine_tools-1.43.0.dist-info}/entry_points.txt +0 -0
- {devsecops_engine_tools-1.42.3.dist-info → devsecops_engine_tools-1.43.0.dist-info}/top_level.txt +0 -0
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/github/github_actions.py
CHANGED
|
@@ -53,7 +53,7 @@ class GithubActions(DevopsPlatformGateway):
|
|
|
53
53
|
return results.get(type)
|
|
54
54
|
|
|
55
55
|
def get_source_code_management_uri(self):
|
|
56
|
-
return f"{SystemVariables.github_server_url}/{SystemVariables.github_repository}"
|
|
56
|
+
return f"{SystemVariables.github_server_url.value()}/{SystemVariables.github_repository.value()}"
|
|
57
57
|
|
|
58
58
|
def get_base_compact_remote_config_url(self, remote_config_repo):
|
|
59
59
|
github_repository = SystemVariables.github_repository.value()
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/container_sca_scan.py
CHANGED
|
@@ -22,7 +22,8 @@ class ContainerScaScan:
|
|
|
22
22
|
secret_tool,
|
|
23
23
|
token_engine_container,
|
|
24
24
|
image_to_scan,
|
|
25
|
-
exclusions
|
|
25
|
+
exclusions,
|
|
26
|
+
pipeline_name,
|
|
26
27
|
):
|
|
27
28
|
self.tool_run = tool_run
|
|
28
29
|
self.remote_config = remote_config
|
|
@@ -33,6 +34,7 @@ class ContainerScaScan:
|
|
|
33
34
|
self.token_engine_container = token_engine_container
|
|
34
35
|
self.image_to_scan = image_to_scan
|
|
35
36
|
self.exclusions = exclusions
|
|
37
|
+
self.pipeline_name = pipeline_name
|
|
36
38
|
|
|
37
39
|
def get_image(self, image_to_scan):
|
|
38
40
|
"""
|
|
@@ -44,13 +46,13 @@ class ContainerScaScan:
|
|
|
44
46
|
return self.tool_images.list_images(image_to_scan)
|
|
45
47
|
|
|
46
48
|
def get_base_image(self, matching_image):
|
|
47
|
-
|
|
49
|
+
"""
|
|
48
50
|
Process the base image.
|
|
49
51
|
|
|
50
52
|
Returns:
|
|
51
53
|
String: base image.
|
|
52
54
|
"""
|
|
53
|
-
|
|
55
|
+
return self.tool_images.get_base_image(matching_image)
|
|
54
56
|
|
|
55
57
|
def get_images_already_scanned(self):
|
|
56
58
|
"""
|
|
@@ -70,6 +72,17 @@ class ContainerScaScan:
|
|
|
70
72
|
with open("scanned_images.txt", "a") as file:
|
|
71
73
|
file.write(result_file + "\n")
|
|
72
74
|
|
|
75
|
+
def validate_base_image_date(self, matching_image, referenced_date):
|
|
76
|
+
"""
|
|
77
|
+
Process the base image date validation.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
string: base image date.
|
|
81
|
+
"""
|
|
82
|
+
return self.tool_images.validate_base_image_date(
|
|
83
|
+
matching_image, referenced_date
|
|
84
|
+
)
|
|
85
|
+
|
|
73
86
|
def process(self):
|
|
74
87
|
"""
|
|
75
88
|
Process SCA scanning.
|
|
@@ -80,8 +93,17 @@ class ContainerScaScan:
|
|
|
80
93
|
base_image = None
|
|
81
94
|
image_scanned = None
|
|
82
95
|
matching_image = self.get_image(self.image_to_scan)
|
|
83
|
-
if self.remote_config[
|
|
96
|
+
if self.remote_config["GET_IMAGE_BASE"]:
|
|
84
97
|
base_image = self.get_base_image(matching_image)
|
|
98
|
+
if self.remote_config["VALIDATE_BASE_IMAGE_DATE"][
|
|
99
|
+
"ENABLED"
|
|
100
|
+
] and not self.exclusions.get(self.pipeline_name, {}).get(
|
|
101
|
+
"VALIDATE_BASE_IMAGE_DATE"
|
|
102
|
+
):
|
|
103
|
+
self.validate_base_image_date(
|
|
104
|
+
matching_image,
|
|
105
|
+
self.remote_config["VALIDATE_BASE_IMAGE_DATE"]["REFERENCE_IMAGE_DATE"],
|
|
106
|
+
)
|
|
85
107
|
sbom_components = None
|
|
86
108
|
generate_sbom = self.remote_config["SBOM"]["ENABLED"] and any(
|
|
87
109
|
branch in str(self.branch)
|
|
@@ -98,7 +120,9 @@ class ContainerScaScan:
|
|
|
98
120
|
self.secret_tool,
|
|
99
121
|
self.token_engine_container,
|
|
100
122
|
image_name,
|
|
101
|
-
result_file,
|
|
123
|
+
result_file,
|
|
124
|
+
base_image,
|
|
125
|
+
self.exclusions,
|
|
102
126
|
generate_sbom,
|
|
103
127
|
)
|
|
104
128
|
self.set_image_scanned(image_name)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from datetime import datetime
|
|
1
2
|
from devsecops_engine_tools.engine_sca.engine_container.src.domain.model.gateways.images_gateway import (
|
|
2
3
|
ImagesGateway,
|
|
3
4
|
)
|
|
@@ -33,18 +34,82 @@ class DockerImages(ImagesGateway):
|
|
|
33
34
|
)
|
|
34
35
|
|
|
35
36
|
def get_base_image(self, matching_image):
|
|
37
|
+
image_details = self.get_image_details(matching_image.id)
|
|
38
|
+
if not image_details:
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
labels = image_details.get("Config", {}).get("Labels", {})
|
|
42
|
+
return self.extract_base_image_from_labels(labels, matching_image)
|
|
43
|
+
|
|
44
|
+
def validate_base_image_date(self, matching_image, referenced_date):
|
|
45
|
+
image_details = self.get_image_details(matching_image.id)
|
|
46
|
+
if not image_details:
|
|
47
|
+
return False
|
|
48
|
+
|
|
49
|
+
labels = image_details.get("Config", {}).get("Labels", {})
|
|
50
|
+
baseline_date = labels.get("x86.baseline.date")
|
|
51
|
+
|
|
52
|
+
if baseline_date:
|
|
53
|
+
date_image = self.parse_date(baseline_date)
|
|
54
|
+
else:
|
|
55
|
+
base_image = self.extract_base_image_from_labels(labels)
|
|
56
|
+
date_image = self.extract_date_from_image(base_image)
|
|
57
|
+
|
|
58
|
+
return self.validate_date(date_image, referenced_date)
|
|
59
|
+
|
|
60
|
+
def get_image_details(self, image_id):
|
|
36
61
|
try:
|
|
37
62
|
client = docker.from_env()
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if source_image:
|
|
42
|
-
logger.info(f"Base image for '{matching_image}' from source-image label: {source_image}")
|
|
43
|
-
return source_image
|
|
44
|
-
|
|
45
|
-
logger.warning(f"Base image not found for '{matching_image}'.")
|
|
63
|
+
return client.api.inspect_image(image_id)
|
|
64
|
+
except Exception as e:
|
|
65
|
+
logger.error(f"Error obtaining image details for '{image_id}': {e}")
|
|
46
66
|
return None
|
|
47
67
|
|
|
68
|
+
def extract_base_image_from_labels(self, labels, matching_image=None):
|
|
69
|
+
try:
|
|
70
|
+
source_image = labels.get("x86.image.name") or labels.get(
|
|
71
|
+
"image.base.ref.name"
|
|
72
|
+
)
|
|
73
|
+
if not source_image:
|
|
74
|
+
source_image = labels.get("source_images") or labels.get("source-image")
|
|
75
|
+
|
|
76
|
+
if source_image and matching_image:
|
|
77
|
+
logger.info(f"Base image for '{matching_image}' found: {source_image}")
|
|
78
|
+
elif matching_image:
|
|
79
|
+
logger.warning(f"Base image not found for '{matching_image}'.")
|
|
80
|
+
|
|
81
|
+
return source_image
|
|
48
82
|
except Exception as e:
|
|
49
|
-
logger.error(f"Error
|
|
50
|
-
return None
|
|
83
|
+
logger.error(f"Error extracting base image from labels: {e}")
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
def extract_date_from_image(self, image_name):
|
|
87
|
+
if not image_name:
|
|
88
|
+
return None
|
|
89
|
+
try:
|
|
90
|
+
date = image_name.split("_")[-1]
|
|
91
|
+
return self.parse_date(date)
|
|
92
|
+
except Exception as e:
|
|
93
|
+
logger.error(f"Error extracting date from image name '{image_name}': {e}")
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
def parse_date(self, date_str):
|
|
97
|
+
try:
|
|
98
|
+
return datetime.strptime(date_str, "%Y%m%d")
|
|
99
|
+
except ValueError:
|
|
100
|
+
logger.error(f"Invalid date format: {date_str}")
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
def validate_date(self, date, referenced_date):
|
|
104
|
+
if not date:
|
|
105
|
+
raise ValueError("Cannot validate date: Invalid or missing date.")
|
|
106
|
+
|
|
107
|
+
reference_date = self.parse_date(referenced_date)
|
|
108
|
+
if not reference_date:
|
|
109
|
+
raise ValueError("Cannot validate date: Referenced date is invalid.")
|
|
110
|
+
|
|
111
|
+
if date < reference_date:
|
|
112
|
+
raise ValueError(
|
|
113
|
+
f"Compliance issue: the source base image date ({date.strftime('%Y-%m-%d')}) is older than the referenced date ({reference_date.strftime('%Y-%m-%d')})."
|
|
114
|
+
)
|
|
115
|
+
return True
|
|
@@ -1 +1 @@
|
|
|
1
|
-
version = '1.
|
|
1
|
+
version = '1.43.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=rgVE2760niT3XN1VMw-ZEBrUP7L5heut-fiAjEx9JwA,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
|
|
@@ -40,7 +40,7 @@ devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/azure/azur
|
|
|
40
40
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
41
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py,sha256=ptzqoY7BkNO4jlna7Uw30mreKZfspwBRqEZMAbhRka4,29969
|
|
42
42
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/github/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
|
-
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/github/github_actions.py,sha256=
|
|
43
|
+
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/github/github_actions.py,sha256=RbZS__LXeeztxumSKZ0aqmkQwKL39q1xdkJDVV_QSMU,4148
|
|
44
44
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_pretty_table/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
45
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_pretty_table/printer_pretty_table.py,sha256=NkXu7JYoCHXIx0HzHl4DhdLGEpocPMIqs2L0ADS-RcI,5369
|
|
46
46
|
devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_rich_table/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -198,16 +198,16 @@ devsecops_engine_tools/engine_sca/engine_container/src/domain/__init__.py,sha256
|
|
|
198
198
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
199
199
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
200
200
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/deserealizator_gateway.py,sha256=sE7-GnNSNLWbA1H0mvTwXmxcOJXl8uvw-0hxMyX4oMc,290
|
|
201
|
-
devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/images_gateway.py,sha256=
|
|
201
|
+
devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/images_gateway.py,sha256=U72tVbOdR75FlitYGp4Wrj7_ZPz0WRsSTRA48goG3Ec,411
|
|
202
202
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/tool_gateway.py,sha256=2fT2DFb4IPqQczCrAI0qEuWQUb3XsqFhI5M0OzNYalo,286
|
|
203
203
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
204
|
-
devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/container_sca_scan.py,sha256=
|
|
204
|
+
devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/container_sca_scan.py,sha256=GvXsT-umEqB-2itAZiwlKIR581w78DbIJNknJ0o7EPw,4925
|
|
205
205
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/handle_remote_config_patterns.py,sha256=4wgBTQSDE-C5v01C3Vxzeq0DJKZUSqQ5TVLG7yPZPKs,926
|
|
206
206
|
devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/set_input_core.py,sha256=2Q-20WqZUCTO5QQxEQnOX8fGlErgOMgiLBCDXBp3xFE,2634
|
|
207
207
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
208
208
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
209
209
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/docker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
210
|
-
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/docker/docker_images.py,sha256=
|
|
210
|
+
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/docker/docker_images.py,sha256=_p-JPfVBrDJBkAxWZHySLc54sMIEe9v1Ut77uTrqlOo,4316
|
|
211
211
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
212
212
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_cloud_manager_scan.py,sha256=tf33YFYB47th4Zu0WtWpsrAm5I6_xCON4yOwFacTQLA,6758
|
|
213
213
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_deserialize_output.py,sha256=oK0NKuPODm38qDgQjf6w40lfNG6NFJS43p5k44wDoMA,2562
|
|
@@ -215,7 +215,7 @@ devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_ada
|
|
|
215
215
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/trivy_deserialize_output.py,sha256=LGqnO10Zt-0-TxUW6F1S46jVktlIwxWSYATKSVblCWI,2535
|
|
216
216
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/trivy_manager_scan.py,sha256=7hGrUU37ZqZKHfkiNX2YrhIlDna8XnhJ3F7ONhneexs,5105
|
|
217
217
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/entry_points/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
218
|
-
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/entry_points/entry_point_tool.py,sha256=
|
|
218
|
+
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/entry_points/entry_point_tool.py,sha256=zCHhb0dFbvPl4kueKroaJfjhra8RWQXxuSOqVOZmg7o,2595
|
|
219
219
|
devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
220
220
|
devsecops_engine_tools/engine_sca/engine_dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
221
221
|
devsecops_engine_tools/engine_sca/engine_dependencies/src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -347,8 +347,8 @@ devsecops_engine_tools/engine_utilities/utils/name_conversion.py,sha256=ADJrRGax
|
|
|
347
347
|
devsecops_engine_tools/engine_utilities/utils/printers.py,sha256=amYAr9YQfYgR6jK9a2l26z3oovFPQ3FAKmhq6BKhEBA,623
|
|
348
348
|
devsecops_engine_tools/engine_utilities/utils/session_manager.py,sha256=Z0fdhB3r-dxU0nGSD9zW_B4r2Qol1rUnUCkhFR0U-HQ,487
|
|
349
349
|
devsecops_engine_tools/engine_utilities/utils/utils.py,sha256=XFap4yOK7ItLWsqbwDhvLd7NpDhs7i-UGJAMD6jjd7w,6687
|
|
350
|
-
devsecops_engine_tools-1.
|
|
351
|
-
devsecops_engine_tools-1.
|
|
352
|
-
devsecops_engine_tools-1.
|
|
353
|
-
devsecops_engine_tools-1.
|
|
354
|
-
devsecops_engine_tools-1.
|
|
350
|
+
devsecops_engine_tools-1.43.0.dist-info/METADATA,sha256=MlWUkXgNemUz4PZ-NRmIWTGmsuWeWYzJj0q5TNOw6XI,11750
|
|
351
|
+
devsecops_engine_tools-1.43.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
|
352
|
+
devsecops_engine_tools-1.43.0.dist-info/entry_points.txt,sha256=MHCTFFs9bdNKo6YcWCcBW2_8X6yTisgLOlmVx-V8Rxc,276
|
|
353
|
+
devsecops_engine_tools-1.43.0.dist-info/top_level.txt,sha256=ge6y0X_xBAU1aG3EMWFtl9djbVyg5BxuSp2r2Lg6EQU,23
|
|
354
|
+
devsecops_engine_tools-1.43.0.dist-info/RECORD,,
|
|
File without changes
|
{devsecops_engine_tools-1.42.3.dist-info → devsecops_engine_tools-1.43.0.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{devsecops_engine_tools-1.42.3.dist-info → devsecops_engine_tools-1.43.0.dist-info}/top_level.txt
RENAMED
|
File without changes
|