devsecops-engine-tools 1.7.16__py3-none-any.whl → 1.7.18__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.

Files changed (21) hide show
  1. devsecops_engine_tools/engine_core/src/applications/runner_engine_core.py +15 -1
  2. devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py +1 -0
  3. devsecops_engine_tools/engine_sast/engine_iac/src/domain/model/config_tool.py +0 -1
  4. devsecops_engine_tools/engine_sast/engine_iac/src/domain/model/gateways/tool_gateway.py +1 -1
  5. devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/driven_adapters/checkov/checkov_tool.py +39 -46
  6. devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/helpers/file_generator_tool.py +19 -19
  7. devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/container_sca_scan.py +39 -5
  8. devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/set_input_core.py +2 -2
  9. devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/docker/docker_images.py +9 -2
  10. devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_cloud_manager_scan.py +51 -70
  11. devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_deserialize_output.py +32 -33
  12. devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/trivy_deserialize_output.py +47 -35
  13. devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/trivy_manager_scan.py +81 -89
  14. devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/entry_points/entry_point_tool.py +5 -4
  15. devsecops_engine_tools/version.py +1 -1
  16. {devsecops_engine_tools-1.7.16.dist-info → devsecops_engine_tools-1.7.18.dist-info}/METADATA +1 -1
  17. {devsecops_engine_tools-1.7.16.dist-info → devsecops_engine_tools-1.7.18.dist-info}/RECORD +20 -21
  18. devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/helpers/images_scanned.py +0 -16
  19. {devsecops_engine_tools-1.7.16.dist-info → devsecops_engine_tools-1.7.18.dist-info}/WHEEL +0 -0
  20. {devsecops_engine_tools-1.7.16.dist-info → devsecops_engine_tools-1.7.18.dist-info}/entry_points.txt +0 -0
  21. {devsecops_engine_tools-1.7.16.dist-info → devsecops_engine_tools-1.7.18.dist-info}/top_level.txt +0 -0
@@ -28,6 +28,20 @@ from devsecops_engine_tools.version import version
28
28
 
29
29
  logger = MyLogger.__call__(**settings.SETTING_LOGGER).get_logger()
30
30
 
31
+ def parse_separated_list(value, choices):
32
+ values = value.split(',')
33
+ # Validar cada elemento de la lista
34
+ for val in values:
35
+ if val not in choices:
36
+ raise argparse.ArgumentTypeError(f"Invalid value: {val}. Valid values are: {', '.join(choices)}")
37
+
38
+ return values
39
+
40
+ def parse_choices(choices):
41
+ def parse_with_choices(value):
42
+ return parse_separated_list(value, choices)
43
+ return parse_with_choices
44
+
31
45
  def get_inputs_from_cli(args):
32
46
  parser = argparse.ArgumentParser()
33
47
  parser.add_argument("-v", "--version", action='version', version='{version}'.format(version=version))
@@ -49,7 +63,7 @@ def get_inputs_from_cli(args):
49
63
  )
50
64
  parser.add_argument("-fp", "--folder_path", type=str, required=False, help="Folder Path to scan, only apply engine_iac tool")
51
65
  parser.add_argument("-p",
52
- "--platform", choices=["eks", "openshift"], type=str, required=False, help="Platform to execute, only apply engine_iac tool"
66
+ "--platform", type=parse_choices({"all", "docker", "k8s", "cloudformation"}), required=False, default="all" ,help="Platform to scan, only apply engine_iac tool"
53
67
  )
54
68
  parser.add_argument(
55
69
  "--use_secrets_manager",
@@ -54,6 +54,7 @@ class DefectDojoPlatform(VulnerabilityManagementGateway):
54
54
  "PRISMA": "Twistlock Image Scan",
55
55
  "XRAY": "JFrog Xray On Demand Binary Scan",
56
56
  "TRUFFLEHOG": "Trufflehog Scan",
57
+ "TRIVY": "Trivy Scan",
57
58
  }
58
59
 
59
60
  if any(
@@ -6,7 +6,6 @@ class ConfigTool:
6
6
  self.version = json_data[tool]["VERSION"]
7
7
  self.search_pattern = json_data["SEARCH_PATTERN"]
8
8
  self.ignore_search_pattern = json_data["IGNORE_SEARCH_PATTERN"]
9
- self.exclusions_path = json_data["EXCLUSIONS_PATH"]
10
9
  self.use_external_checks_git = json_data[tool]["USE_EXTERNAL_CHECKS_GIT"]
11
10
  self.external_checks_git = json_data[tool]["EXTERNAL_CHECKS_GIT"]
12
11
  self.repository_ssh_host = json_data[tool]["EXTERNAL_GIT_SSH_HOST"]
@@ -2,5 +2,5 @@ from abc import ABCMeta, abstractmethod
2
2
 
3
3
  class ToolGateway(metaclass=ABCMeta):
4
4
  @abstractmethod
5
- def run_tool(self, config_tool, folders_to_scan, environment, container_platform, secret_tool):
5
+ def run_tool(self, config_tool, folders_to_scan, environment, platform_to_scan, secret_tool):
6
6
  "run_tool"
@@ -38,6 +38,7 @@ class CheckovTool(ToolGateway):
38
38
  CHECKOV_CONFIG_FILE = "checkov_config.yaml"
39
39
  TOOL = "CHECKOV"
40
40
  framework_mapping = {"RULES_DOCKER": "dockerfile", "RULES_K8S": "kubernetes", "RULES_CLOUDFORMATION": "cloudformation"}
41
+ framework_external_checks = ["RULES_K8S", "RULES_CLOUDFORMATION","RULES_DOCKER"]
41
42
 
42
43
 
43
44
  def create_config_file(self, checkov_config: CheckovConfig):
@@ -113,58 +114,50 @@ class CheckovTool(ToolGateway):
113
114
  output = self.execute(checkov_config)
114
115
  result.append(json.loads(output))
115
116
  queue.put(result)
116
-
117
- def if_platform(self,value,container_platform):
118
- if value.get("platform_not_apply"):
119
- if value.get("platform_not_apply") != container_platform:
120
- return True
121
- else:
122
- return False
123
- else:
124
- return True
125
117
 
126
118
  def scan_folders(
127
- self, folders_to_scan, config_tool: ConfigTool, agent_env, environment, container_platform
119
+ self, folders_to_scan, config_tool: ConfigTool, agent_env, environment, platform_to_scan
128
120
  ):
129
121
  output_queue = queue.Queue()
130
122
  # Crea una lista para almacenar los hilos
131
123
  threads = []
132
124
  for folder in folders_to_scan:
133
125
  for rule in config_tool.rules_data_type:
134
- checkov_config = CheckovConfig(
135
- path_config_file="",
136
- config_file_name=rule,
137
- framework=self.framework_mapping[rule],
138
- checks=[
139
- key
140
- for key, value in config_tool.rules_data_type[rule].items()
141
- if value["environment"].get(environment) and self.if_platform(value,container_platform)
142
- ],
143
- soft_fail=False,
144
- directories=folder,
145
- external_checks_git=[
146
- f"{config_tool.external_checks_git}/{self.framework_mapping[rule]}"
147
- ]
148
- if config_tool.use_external_checks_git == "True"
149
- and agent_env is not None
150
- and rule in ["RULES_K8S", "RULES_CLOUDFORMATION","RULES_DOCKER"]
151
- else [],
152
- env=agent_env,
153
- external_checks_dir=f"/tmp/rules/{self.framework_mapping[rule]}"
154
- if config_tool.use_external_checks_dir == "True"
155
- and rule in ["RULES_K8S", "RULES_CLOUDFORMATION","RULES_DOCKER"]
156
- else [],
157
- )
158
-
159
- checkov_config.create_config_dict()
160
- self.create_config_file(checkov_config)
161
- config_tool.rules_all.update(config_tool.rules_data_type[rule])
162
- t = threading.Thread(
163
- target=self.async_scan,
164
- args=(output_queue, checkov_config),
165
- )
166
- t.start()
167
- threads.append(t)
126
+ if "all" in platform_to_scan or any(elem.upper() in rule for elem in platform_to_scan):
127
+ checkov_config = CheckovConfig(
128
+ path_config_file="",
129
+ config_file_name=rule,
130
+ framework=self.framework_mapping[rule],
131
+ checks=[
132
+ key
133
+ for key, value in config_tool.rules_data_type[rule].items()
134
+ if value["environment"].get(environment)
135
+ ],
136
+ soft_fail=False,
137
+ directories=folder,
138
+ external_checks_git=[
139
+ f"{config_tool.external_checks_git}/{self.framework_mapping[rule]}"
140
+ ]
141
+ if config_tool.use_external_checks_git == "True"
142
+ and agent_env is not None
143
+ and rule in self.framework_external_checks
144
+ else [],
145
+ env=agent_env,
146
+ external_checks_dir=f"/tmp/rules/{self.framework_mapping[rule]}"
147
+ if config_tool.use_external_checks_dir == "True"
148
+ and rule in self.framework_external_checks
149
+ else [],
150
+ )
151
+
152
+ checkov_config.create_config_dict()
153
+ self.create_config_file(checkov_config)
154
+ config_tool.rules_all.update(config_tool.rules_data_type[rule])
155
+ t = threading.Thread(
156
+ target=self.async_scan,
157
+ args=(output_queue, checkov_config),
158
+ )
159
+ t.start()
160
+ threads.append(t)
168
161
  # Espera a que todos los hilos terminen
169
162
  for t in threads:
170
163
  t.join()
@@ -176,12 +169,12 @@ class CheckovTool(ToolGateway):
176
169
  return result_scans
177
170
 
178
171
  def run_tool(
179
- self, config_tool: ConfigTool, folders_to_scan, environment, container_platform, secret_tool
172
+ self, config_tool: ConfigTool, folders_to_scan, environment, platform_to_scan, secret_tool
180
173
  ):
181
174
  agent_env = self.configurate_external_checks(config_tool, secret_tool)
182
175
 
183
176
  result_scans = self.scan_folders(
184
- folders_to_scan, config_tool, agent_env, environment, container_platform
177
+ folders_to_scan, config_tool, agent_env, environment, platform_to_scan
185
178
  )
186
179
 
187
180
  checkov_deserealizator = CheckovDeserealizator()
@@ -35,27 +35,27 @@ def generate_file_from_tool(tool, result_list, rules_doc):
35
35
  "checkov_version", None
36
36
  )
37
37
 
38
- file_name = "results.json"
39
- results_data = {
40
- "check_type": "Dockerfile, Kubernetes and CloudFormation",
41
- "results": {
42
- "failed_checks": all_failed_checks,
43
- },
44
- "summary": {
45
- "passed": summary_passed,
46
- "failed": summary_failed,
47
- "skipped": summary_skipped,
48
- "parsing_errors": summary_parsing_errors,
49
- "resource_count": summary_resource_count,
50
- "checkov_version": checkov_version,
51
- },
52
- }
38
+ file_name = "results.json"
39
+ results_data = {
40
+ "check_type": "Dockerfile, Kubernetes and CloudFormation",
41
+ "results": {
42
+ "failed_checks": all_failed_checks,
43
+ },
44
+ "summary": {
45
+ "passed": summary_passed,
46
+ "failed": summary_failed,
47
+ "skipped": summary_skipped,
48
+ "parsing_errors": summary_parsing_errors,
49
+ "resource_count": summary_resource_count,
50
+ "checkov_version": checkov_version,
51
+ },
52
+ }
53
53
 
54
- with open(file_name, "w") as json_file:
55
- json.dump(results_data, json_file, indent=4)
54
+ with open(file_name, "w") as json_file:
55
+ json.dump(results_data, json_file, indent=4)
56
56
 
57
- absolute_path = os.path.abspath(file_name)
58
- return absolute_path
57
+ absolute_path = os.path.abspath(file_name)
58
+ return absolute_path
59
59
  except Exception as ex:
60
60
  logger.error(f"Error during handling checkov json integrator {ex}")
61
61
 
@@ -8,6 +8,8 @@ from devsecops_engine_tools.engine_sca.engine_container.src.domain.model.gateway
8
8
  DeseralizatorGateway,
9
9
  )
10
10
 
11
+ import os
12
+
11
13
 
12
14
  class ContainerScaScan:
13
15
  def __init__(
@@ -26,7 +28,7 @@ class ContainerScaScan:
26
28
  self.build_id = build_id
27
29
  self.token = token
28
30
 
29
- def scan_image(self):
31
+ def get_latest_image(self):
30
32
  """
31
33
  Process the list of images.
32
34
 
@@ -35,16 +37,48 @@ class ContainerScaScan:
35
37
  """
36
38
  return self.tool_images.list_images()
37
39
 
40
+ def get_images_already_scanned(self):
41
+ """
42
+ Create images scanned file if it does not exist and get the images that have already been scanned.
43
+ """
44
+ scanned_images_file = os.path.join(os.getcwd(), "scanned_images.txt")
45
+ if not os.path.exists(scanned_images_file):
46
+ open(scanned_images_file, "w").close()
47
+ with open(scanned_images_file, "r") as file:
48
+ images_scanned = file.read().splitlines()
49
+ return images_scanned
50
+
51
+ def set_image_scanned(self, result_file):
52
+ """
53
+ Write in scanned_images.txt the result file
54
+ """
55
+ with open("scanned_images.txt", "a") as file:
56
+ file.write(result_file + "\n")
57
+
38
58
  def process(self):
39
59
  """
40
60
  Process SCA scanning.
41
61
 
42
62
  Returns:
43
- dict: SCA scanning results.
63
+ string: file scanning results name.
44
64
  """
45
- return self.tool_run.run_tool_container_sca(
46
- self.remote_config, self.token, self.scan_image(), self.build_id
47
- )
65
+ latest_image = self.get_latest_image()
66
+ image_name = latest_image.tags[0]
67
+ image_scanned = None
68
+ if str(self.build_id) in image_name:
69
+ result_file = image_name + "_scan_result.json"
70
+ if result_file in self.get_images_already_scanned():
71
+ print(f"The image {image_name} has already been scanned previously.")
72
+ return image_scanned
73
+ image_scanned = self.tool_run.run_tool_container_sca(
74
+ self.remote_config, self.token, image_name, result_file
75
+ )
76
+ self.set_image_scanned(result_file)
77
+ else:
78
+ print(
79
+ f"'{image_name}' name does not contain build number '{self.build_id}'. Tool skipped."
80
+ )
81
+ return image_scanned
48
82
 
49
83
  def deseralizator(self, image_scanned):
50
84
  """
@@ -31,7 +31,7 @@ class SetInputCore:
31
31
  ]
32
32
  return list_exclusions
33
33
 
34
- def set_input_core(self, images_scanned):
34
+ def set_input_core(self, image_scanned):
35
35
  """
36
36
  Set the input core.
37
37
 
@@ -45,7 +45,7 @@ class SetInputCore:
45
45
  self.tool,
46
46
  ),
47
47
  Threshold(self.remote_config["THRESHOLD"]),
48
- images_scanned[-1] if images_scanned else None,
48
+ image_scanned,
49
49
  self.remote_config["MESSAGE_INFO_ENGINE_CONTAINER"],
50
50
  self.pipeline_name,
51
51
  self.stage.capitalize(),
@@ -4,6 +4,11 @@ from devsecops_engine_tools.engine_sca.engine_container.src.domain.model.gateway
4
4
  )
5
5
  import docker
6
6
 
7
+ from devsecops_engine_tools.engine_utilities.utils.logger_info import MyLogger
8
+ from devsecops_engine_tools.engine_utilities import settings
9
+
10
+ logger = MyLogger.__call__(**settings.SETTING_LOGGER).get_logger()
11
+
7
12
 
8
13
  class DockerImages(ImagesGateway):
9
14
  def list_images(self):
@@ -18,5 +23,7 @@ class DockerImages(ImagesGateway):
18
23
  print("Tag last image:", latest_image.tags)
19
24
  print("Created date last image:", latest_image.attrs["Created"])
20
25
  return latest_image
21
- except subprocess.CalledProcessError as e:
22
- raise ValueError(f"Error listing images:{e.stderr}")
26
+ except Exception as e:
27
+ logger.error(
28
+ f"Error listing images, docker must be running and added to PATH: {e}"
29
+ )
@@ -4,9 +4,6 @@ import os
4
4
  import subprocess
5
5
  import logging
6
6
  import base64
7
- from devsecops_engine_tools.engine_sca.engine_container.src.infrastructure.helpers.images_scanned import (
8
- ImagesScanned,
9
- )
10
7
  from devsecops_engine_tools.engine_sca.engine_container.src.domain.model.gateways.tool_gateway import (
11
8
  ToolGateway,
12
9
  )
@@ -44,76 +41,60 @@ class PrismaCloudManagerScan(ToolGateway):
44
41
  except Exception as e:
45
42
  raise ValueError(f"Error downloading twistcli: {e}")
46
43
 
47
- def scan_image(self, file_path, image, remoteconfig, prisma_secret_key, build_id):
48
- file_name = "scanned_images.txt"
49
- image_name = f"{image.tags[0]}"
50
- result_file = f"{image_name}" + "_scan_result.json"
51
- images_scanned = []
52
-
53
- if (result_file) in ImagesScanned.get_images_already_scanned(file_name):
54
- print(f"The image {image_name} has already been scanned previously.")
55
- else:
56
- if build_id in image_name:
57
- command = (
58
- file_path,
59
- "images",
60
- "scan",
61
- "--address",
62
- remoteconfig["PRISMA_CLOUD"]["PRISMA_CONSOLE_URL"],
63
- "--user",
64
- remoteconfig["PRISMA_CLOUD"]["PRISMA_ACCESS_KEY"],
65
- "--password",
66
- prisma_secret_key,
67
- "--output-file",
68
- result_file,
69
- "--details",
70
- image_name,
71
- )
72
- try:
73
- subprocess.run(
74
- command,
75
- check=True,
76
- stdout=subprocess.PIPE,
77
- stderr=subprocess.PIPE,
78
- text=True,
79
- )
80
- images_scanned.append(result_file)
81
- print(f"The image {image_name} was scanned")
82
- with open(file_name, "a") as file:
83
- file.write(result_file + "\n")
84
- except subprocess.CalledProcessError as e:
85
- logger.error(f"Error during image scan of {image_name}: {e.stderr}")
86
-
87
- return images_scanned
88
-
89
- def run_tool_container_sca(self, remoteconfig, prisma_secret_key, image, build_id):
90
- images_scanned = []
44
+ def scan_image(
45
+ self, file_path, image_name, result_file, remoteconfig, prisma_secret_key
46
+ ):
47
+ command = (
48
+ file_path,
49
+ "images",
50
+ "scan",
51
+ "--address",
52
+ remoteconfig["PRISMA_CLOUD"]["PRISMA_CONSOLE_URL"],
53
+ "--user",
54
+ remoteconfig["PRISMA_CLOUD"]["PRISMA_ACCESS_KEY"],
55
+ "--password",
56
+ prisma_secret_key,
57
+ "--output-file",
58
+ result_file,
59
+ "--details",
60
+ image_name,
61
+ )
91
62
  try:
92
- file_path = os.path.join(
93
- os.getcwd(), remoteconfig["PRISMA_CLOUD"]["TWISTCLI_PATH"]
63
+ subprocess.run(
64
+ command,
65
+ check=True,
66
+ stdout=subprocess.PIPE,
67
+ stderr=subprocess.PIPE,
68
+ text=True,
94
69
  )
70
+ print(f"The image {image_name} was scanned")
95
71
 
96
- if not os.path.exists(file_path):
97
- self.download_twistcli(
98
- file_path,
99
- remoteconfig["PRISMA_CLOUD"]["PRISMA_ACCESS_KEY"],
100
- prisma_secret_key,
101
- remoteconfig["PRISMA_CLOUD"]["PRISMA_CONSOLE_URL"],
102
- remoteconfig["PRISMA_CLOUD"]["PRISMA_API_VERSION"],
103
- )
104
- images_scanned.extend(
105
- self.scan_image(
106
- file_path,
107
- image,
108
- remoteconfig,
109
- prisma_secret_key,
110
- build_id,
111
- )
112
- )
72
+ return result_file
73
+
74
+ except subprocess.CalledProcessError as e:
75
+ logger.error(f"Error during image scan of {image_name}: {e.stderr}")
113
76
 
114
- return images_scanned
77
+ def run_tool_container_sca(
78
+ self, remoteconfig, prisma_secret_key, image_name, result_file
79
+ ):
80
+ file_path = os.path.join(
81
+ os.getcwd(), remoteconfig["PRISMA_CLOUD"]["TWISTCLI_PATH"]
82
+ )
115
83
 
116
- except Exception as ex:
117
- logger.error(f"An overall error occurred: {ex}")
84
+ if not os.path.exists(file_path):
85
+ self.download_twistcli(
86
+ file_path,
87
+ remoteconfig["PRISMA_CLOUD"]["PRISMA_ACCESS_KEY"],
88
+ prisma_secret_key,
89
+ remoteconfig["PRISMA_CLOUD"]["PRISMA_CONSOLE_URL"],
90
+ remoteconfig["PRISMA_CLOUD"]["PRISMA_API_VERSION"],
91
+ )
92
+ image_scanned = self.scan_image(
93
+ file_path,
94
+ image_name,
95
+ result_file,
96
+ remoteconfig,
97
+ prisma_secret_key,
98
+ )
118
99
 
119
- return images_scanned
100
+ return image_scanned
@@ -12,7 +12,7 @@ import json
12
12
 
13
13
  @dataclass
14
14
  class PrismaDeserealizator(DeseralizatorGateway):
15
- def get_list_findings(self, images_scanned: list) -> "list[Finding]":
15
+ def get_list_findings(self, image_scanned) -> "list[Finding]":
16
16
  list_open_vulnerabilities = []
17
17
  SEVERITY_MAP = {
18
18
  "unimportant": "low",
@@ -26,40 +26,39 @@ class PrismaDeserealizator(DeseralizatorGateway):
26
26
  "important": "high",
27
27
  "critical": "critical",
28
28
  }
29
- for image in images_scanned:
30
- with open(image, "rb") as file:
31
- image_object = file.read()
29
+ with open(image_scanned, "rb") as file:
30
+ image_object = file.read()
32
31
 
33
- json_data = json.loads(image_object)
34
- vulnerabilities_data = (
35
- json_data["results"][0]["vulnerabilities"]
36
- if "vulnerabilities" in json_data["results"][0]
37
- else []
38
- )
32
+ json_data = json.loads(image_object)
33
+ vulnerabilities_data = (
34
+ json_data["results"][0]["vulnerabilities"]
35
+ if "vulnerabilities" in json_data["results"][0]
36
+ else []
37
+ )
39
38
 
40
- # Create a list of findings instances from the JSON data
41
- vulnerabilities = [
42
- Finding(
43
- id=vul.get("id", ""),
44
- cvss=float(vul.get("cvss", 0.0)),
45
- where=vul.get("packageName", "")
46
- + ":"
47
- + vul.get("packageVersion", ""),
48
- description=vul.get("description", "")[:150],
49
- severity=SEVERITY_MAP.get(vul.get("severity", ""), ""),
50
- identification_date=datetime.strptime(
51
- vul.get("discoveredDate", ""), "%Y-%m-%dT%H:%M:%S%z"
52
- ),
53
- published_date_cve=vul.get("publishedDate", None),
54
- module="engine_container",
55
- category=Category.VULNERABILITY,
56
- requirements=vul.get("status", ""),
57
- tool="PrismaCloud",
58
- )
59
- for vul in vulnerabilities_data
60
- ]
39
+ # Create a list of findings instances from the JSON data
40
+ vulnerabilities = [
41
+ Finding(
42
+ id=vul.get("id", ""),
43
+ cvss=float(vul.get("cvss", 0.0)),
44
+ where=vul.get("packageName", "")
45
+ + ":"
46
+ + vul.get("packageVersion", ""),
47
+ description=vul.get("description", "")[:150],
48
+ severity=SEVERITY_MAP.get(vul.get("severity", ""), ""),
49
+ identification_date=datetime.strptime(
50
+ vul.get("discoveredDate", ""), "%Y-%m-%dT%H:%M:%S%z"
51
+ ),
52
+ published_date_cve=vul.get("publishedDate", "").replace("Z", "+00:00"),
53
+ module="engine_container",
54
+ category=Category.VULNERABILITY,
55
+ requirements=vul.get("status", ""),
56
+ tool="PrismaCloud",
57
+ )
58
+ for vul in vulnerabilities_data
59
+ ]
61
60
 
62
- # Add the Vulnerability instances to the list
63
- list_open_vulnerabilities.extend(vulnerabilities)
61
+ # Add the Vulnerability instances to the list
62
+ list_open_vulnerabilities.extend(vulnerabilities)
64
63
 
65
64
  return list_open_vulnerabilities
@@ -7,45 +7,57 @@ from devsecops_engine_tools.engine_core.src.domain.model.finding import (
7
7
  )
8
8
  from dataclasses import dataclass
9
9
  import json
10
- from datetime import datetime
10
+ from datetime import datetime, timezone
11
11
 
12
12
 
13
13
  @dataclass
14
14
  class TrivyDeserializator(DeseralizatorGateway):
15
- def get_list_findings(self, images_scanned: list) -> "list[Finding]":
15
+ def check_date_format(self, vul):
16
+ try:
17
+ published_date_cve=datetime.strptime(
18
+ vul.get("PublishedDate"),
19
+ "%Y-%m-%dT%H:%M:%S.%fZ"
20
+ ).replace(tzinfo=timezone.utc).isoformat()
21
+ except:
22
+ published_date_cve=datetime.strptime(
23
+ vul.get("PublishedDate"),
24
+ "%Y-%m-%dT%H:%M:%SZ"
25
+ ).replace(tzinfo=timezone.utc).isoformat()
26
+ return published_date_cve
27
+
28
+ def get_list_findings(self, image_scanned) -> "list[Finding]":
16
29
  list_open_vulnerabilities = []
17
- for image in images_scanned:
18
- with open(image, "rb") as file:
19
- image_object = file.read()
20
- json_data = json.loads(image_object)
21
- vulnerabilities_data = json_data["Results"][0]["Vulnerabilities"]
22
- vulnerabilities = [
23
- Finding(
24
- id=vul.get("VulnerabilityID", ""),
25
- cvss=next(
26
- (
27
- v["V3Score"]
28
- for v in vul["CVSS"].values()
29
- if "V3Score" in v
30
- ),
31
- None,
32
- ),
33
- where=vul.get("PkgName", "")
34
- + " "
35
- + vul.get("InstalledVersion", ""),
36
- description=vul.get("Description", "").replace("\n", ""),
37
- severity=vul.get("Severity", "").lower(),
38
- identification_date=datetime.now().strftime(
39
- "%d-%m-%Y %H:%M:%S"
30
+ with open(image_scanned, "rb") as file:
31
+ image_object = file.read()
32
+ json_data = json.loads(image_object)
33
+ vulnerabilities_data = json_data["Results"][0].get("Vulnerabilities", [])
34
+ vulnerabilities = [
35
+ Finding(
36
+ id=vul.get("VulnerabilityID", ""),
37
+ cvss=str(next(
38
+ (
39
+ v["V3Score"]
40
+ for v in vul["CVSS"].values()
41
+ if "V3Score" in v
40
42
  ),
41
- published_date_cve=vul.get("PublishedDate", ""),
42
- module="engine_container",
43
- category=Category.VULNERABILITY,
44
- requirements=vul.get("FixedVersion") or vul.get("Status", ""),
45
- tool="Trivy",
46
- )
47
- for vul in vulnerabilities_data
48
- if "CVSS" in vul
49
- ]
50
- list_open_vulnerabilities.extend(vulnerabilities)
43
+ None,
44
+ )),
45
+ where=vul.get("PkgName", "")
46
+ + " "
47
+ + vul.get("InstalledVersion", ""),
48
+ description=vul.get("Description", "").replace("\n", "")[:150],
49
+ severity=vul.get("Severity", "").lower(),
50
+ identification_date=datetime.now().strftime(
51
+ "%Y-%m-%dT%H:%M:%S%z"
52
+ ),
53
+ published_date_cve=self.check_date_format(vul),
54
+ module="engine_container",
55
+ category=Category.VULNERABILITY,
56
+ requirements=vul.get("FixedVersion") or vul.get("Status", ""),
57
+ tool="Trivy",
58
+ )
59
+ for vul in vulnerabilities_data
60
+ if vul.get("CVSS") and vul.get("PublishedDate")
61
+ ]
62
+ list_open_vulnerabilities.extend(vulnerabilities)
51
63
  return list_open_vulnerabilities
@@ -1,13 +1,12 @@
1
- import subprocess
2
- import re
3
-
4
1
  from devsecops_engine_tools.engine_sca.engine_container.src.domain.model.gateways.tool_gateway import (
5
2
  ToolGateway,
6
3
  )
7
4
 
8
- from devsecops_engine_tools.engine_sca.engine_container.src.infrastructure.helpers.images_scanned import (
9
- ImagesScanned,
10
- )
5
+ import subprocess
6
+ import platform
7
+ import requests
8
+ import tarfile
9
+ import zipfile
11
10
 
12
11
  from devsecops_engine_tools.engine_utilities.utils.logger_info import MyLogger
13
12
  from devsecops_engine_tools.engine_utilities import settings
@@ -16,99 +15,92 @@ logger = MyLogger.__call__(**settings.SETTING_LOGGER).get_logger()
16
15
 
17
16
 
18
17
  class TrivyScan(ToolGateway):
19
- def install_tool(self, version):
18
+ def download_tool(self, file, url):
19
+ try:
20
+ response = requests.get(url, allow_redirects=True)
21
+ with open(file, "wb") as compress_file:
22
+ compress_file.write(response.content)
23
+ except Exception as e:
24
+ logger.error(f"Error downloading trivy: {e}")
25
+
26
+ def install_tool(self, file, url):
20
27
  installed = subprocess.run(
21
- ["which", "trivy"],
28
+ ["which", "./trivy"],
22
29
  stdout=subprocess.PIPE,
23
30
  stderr=subprocess.PIPE,
24
31
  )
25
32
  if installed.returncode == 1:
26
33
  try:
27
- command1 = [
28
- "wget",
29
- "https://github.com/aquasecurity/trivy/releases/download/v"
30
- + version
31
- + "/trivy_"
32
- + version
33
- + "_Linux-64bit.deb",
34
- ]
35
- subprocess.run(
36
- command1, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
37
- )
38
- command2 = [
39
- "sudo",
40
- "dpkg",
41
- "-i",
42
- "trivy_" + version + "_Linux-64bit.deb",
43
- ]
44
- subprocess.run(
45
- command2, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
46
- )
47
- except subprocess.CalledProcessError as error:
48
- raise RuntimeError(f"Error al instalar trivy: {error}")
49
-
50
- def scan_image(self, repository, tag, remoteconfig, release):
51
- file_name = "scanned_images.txt"
52
- repo = repository.split("/")[1] if len(repository.split("/")) >= 2 else ""
53
- image_name = f"{repository}:{tag}"
54
- result_file = f"{repo}:{tag}" + "_scan_result.json"
55
- images_scanned = []
34
+ self.download_tool(file, url)
35
+ with tarfile.open(file, 'r:gz') as tar_file:
36
+ tar_file.extract(member=tar_file.getmember("trivy"))
37
+ except Exception as e:
38
+ logger.error(f"Error installing trivy: {e}")
39
+
40
+ def install_tool_windows(self, file, url):
41
+ try:
42
+ subprocess.run(
43
+ ["./trivy.exe", "--version"],
44
+ stdout=subprocess.PIPE,
45
+ stderr=subprocess.PIPE,
46
+ )
47
+ except:
48
+ try:
49
+ self.download_tool(file, url)
50
+ with zipfile.ZipFile(file, 'r') as zip_file:
51
+ zip_file.extract(member="trivy.exe")
52
+ except Exception as e:
53
+ logger.error(f"Error installing trivy: {e}")
56
54
 
57
- if not ((result_file) in ImagesScanned.get_images_already_scanned(file_name)):
58
- pattern = remoteconfig["REGEX_EXPRESSION_PROJECTS"]
59
- match = re.match(pattern, repo.upper())
60
- if match:
61
- if match.group() in release.upper():
62
- command1 = ["trivy", "image", "--download-db-only"]
63
- command2 = [
64
- "trivy",
65
- "--scanners",
66
- "vuln",
67
- "-f",
68
- "json",
69
- "-o",
70
- result_file,
71
- ]
72
- command2.extend(["--quiet", "image", image_name])
73
- try:
74
- subprocess.run(
75
- command1,
76
- check=True,
77
- stdout=subprocess.PIPE,
78
- stderr=subprocess.PIPE,
79
- )
80
- subprocess.run(
81
- command2,
82
- check=True,
83
- stdout=subprocess.PIPE,
84
- stderr=subprocess.PIPE,
85
- text=True,
86
- )
87
- images_scanned.append(result_file)
88
- with open(file_name, "a") as file:
89
- file.write(result_file + "\n")
90
- except subprocess.CalledProcessError as e:
91
- logger.error(
92
- f"Error during image scan of {repository}: {e.stderr}"
93
- )
55
+ def scan_image(self, prefix, image_name, result_file):
56
+ command = [
57
+ prefix,
58
+ "--scanners",
59
+ "vuln",
60
+ "-f",
61
+ "json",
62
+ "-o",
63
+ result_file,
64
+ ]
65
+ command.extend(["--quiet", "image", image_name])
66
+ try:
67
+ subprocess.run(
68
+ command,
69
+ check=True,
70
+ stdout=subprocess.PIPE,
71
+ stderr=subprocess.PIPE,
72
+ text=True,
73
+ )
74
+ print(f"The image {image_name} was scanned")
94
75
 
95
- return images_scanned
76
+ return result_file
96
77
 
97
- def run_tool_container_sca(self, remoteconfig, token, scan_image, release):
98
- try:
99
- trivy_version = remoteconfig["TRIVY"]["TRIVY_VERSION"]
100
- self.install_tool(trivy_version)
101
- images_scanned = []
78
+ except Exception as e:
79
+ logger.error(f"Error during image scan of {image_name}: {e}")
102
80
 
103
- for image in scan_image:
104
- repository, tag = image["Repository"], image["Tag"]
105
- images_scanned.extend(
106
- self.scan_image(repository, tag, remoteconfig, release)
107
- )
81
+ def run_tool_container_sca(self, remoteconfig, token, image_name, result_file):
82
+ trivy_version = remoteconfig["TRIVY"]["TRIVY_VERSION"]
83
+ os_platform = platform.system()
84
+ base_url = f"https://github.com/aquasecurity/trivy/releases/download/v{trivy_version}/"
108
85
 
109
- return images_scanned
86
+ if os_platform == "Linux":
87
+ file=f"trivy_{trivy_version}_Linux-64bit.tar.gz"
88
+ self.install_tool(file, base_url+file)
89
+ command_prefix = "./trivy"
90
+ elif os_platform == "Darwin":
91
+ file=f"trivy_{trivy_version}_macOS-64bit.tar.gz"
92
+ self.install_tool(file, base_url+file)
93
+ command_prefix = "./trivy"
94
+ elif os_platform == "Windows":
95
+ file=f"trivy_{trivy_version}_windows-64bit.zip"
96
+ self.install_tool_windows(file, base_url+file)
97
+ command_prefix = "./trivy.exe"
98
+ else:
99
+ logger.warning(f"{os_platform} is not supported.")
100
+ return None
110
101
 
111
- except Exception as ex:
112
- logger.error(f"An overall error occurred: {ex}")
102
+ image_scanned = (
103
+ self.scan_image(command_prefix, image_name, result_file)
104
+ )
113
105
 
114
- return 0
106
+ return image_scanned
@@ -36,7 +36,7 @@ def init_engine_sca_rm(
36
36
  scan_flag = handle_remote_config_patterns.ignore_analysis_pattern()
37
37
  build_id = tool_remote.get_variable("build_id")
38
38
  stage = tool_remote.get_variable("stage")
39
- images_scanned = []
39
+ image_scanned = None
40
40
  deseralized = []
41
41
  input_core = SetInputCore(remote_config, exclusions, pipeline_name, tool, stage)
42
42
  if scan_flag and not (skip_flag):
@@ -48,11 +48,12 @@ def init_engine_sca_rm(
48
48
  build_id,
49
49
  token,
50
50
  )
51
- images_scanned = container_sca_scan.process()
52
- deseralized = container_sca_scan.deseralizator(images_scanned)
51
+ image_scanned = container_sca_scan.process()
52
+ if image_scanned:
53
+ deseralized = container_sca_scan.deseralizator(image_scanned)
53
54
  else:
54
55
  print("Tool skipped by DevSecOps policy")
55
56
  logger.info("Tool skipped by DevSecOps policy")
56
- core_input = input_core.set_input_core(images_scanned)
57
+ core_input = input_core.set_input_core(image_scanned)
57
58
 
58
59
  return deseralized, core_input
@@ -1 +1 @@
1
- version = '1.7.16'
1
+ version = '1.7.18'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: devsecops-engine-tools
3
- Version: 1.7.16
3
+ Version: 1.7.18
4
4
  Summary: Tool for DevSecOps strategy
5
5
  Home-page: https://github.com/bancolombia/devsecops-engine-tools
6
6
  Author: Bancolombia DevSecOps Team
@@ -1,9 +1,9 @@
1
1
  devsecops_engine_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- devsecops_engine_tools/version.py,sha256=vVlXeXuVsZX9q82mpgg-l8td6DNWeMF45zXX4TerVqA,18
2
+ devsecops_engine_tools/version.py,sha256=uHp5xMfNM22KDFIlPApHm9JbkzWEjgI-J44tqG0qvgY,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=N62RsNN9aM2dhLQDNtDqDRRS0oo9zGnyjEotNaPmrMI,5169
6
+ devsecops_engine_tools/engine_core/src/applications/runner_engine_core.py,sha256=17BPgOOIu21bsIsu319Q-7HUMYXjMUtxVf17tPA8BOU,5650
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
@@ -36,7 +36,7 @@ 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=Ot1j5my-iEpU-ZYy9yNXkwmwLOmJ3f95JyyAUcpFN5g,4967
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=fnyexfnIfFyP4iCLTeMwWa6OaEP_VYcnPg8roANIKGs,10864
39
+ devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/defect_dojo/defect_dojo.py,sha256=qOqipt7P6THEjoaBwpIPO8OEN9OKpW6u_X_c4DeGhx8,10903
40
40
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_pretty_table/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
41
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/printer_pretty_table/printer_pretty_table.py,sha256=Tz056qYuIKrdYGKyoPo7xFdOpfN3A0YMd3cCSAGVrYQ,3828
42
42
  devsecops_engine_tools/engine_core/src/infrastructure/driven_adapters/runtime_local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -84,9 +84,9 @@ devsecops_engine_tools/engine_sast/engine_iac/src/deployment/__init__.py,sha256=
84
84
  devsecops_engine_tools/engine_sast/engine_iac/src/deployment/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
85
  devsecops_engine_tools/engine_sast/engine_iac/src/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
86
86
  devsecops_engine_tools/engine_sast/engine_iac/src/domain/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
- devsecops_engine_tools/engine_sast/engine_iac/src/domain/model/config_tool.py,sha256=aED1_wtWYENRazT_OvumQbtWIvAne4wHCV-BrLig2Jw,1303
87
+ devsecops_engine_tools/engine_sast/engine_iac/src/domain/model/config_tool.py,sha256=NLV61UALqRWJHq4uvxcH4CugtQGMAwCr-RM5UvZuUC8,1243
88
88
  devsecops_engine_tools/engine_sast/engine_iac/src/domain/model/gateways/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
- devsecops_engine_tools/engine_sast/engine_iac/src/domain/model/gateways/tool_gateway.py,sha256=ep5luExG_wj8csjUUkecCq83jwi7Z8qogSPbexmZyUM,218
89
+ devsecops_engine_tools/engine_sast/engine_iac/src/domain/model/gateways/tool_gateway.py,sha256=tqOkmy5fRMvCFjuQUSdGdWd-PrShtJi0YDlAQ8htMzM,216
90
90
  devsecops_engine_tools/engine_sast/engine_iac/src/domain/usecases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
91
91
  devsecops_engine_tools/engine_sast/engine_iac/src/domain/usecases/iac_scan.py,sha256=ijFVq_acgzGJ58p-L9mApn7kmgJKiD8mih99Jncorcc,4995
92
92
  devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -94,11 +94,11 @@ devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/driven_adapters
94
94
  devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/driven_adapters/checkov/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
95
  devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/driven_adapters/checkov/checkov_config.py,sha256=qbE6wUO5_WFXF_QolL0JYelaRGEOUakPEZR_6HAKzzI,4355
96
96
  devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/driven_adapters/checkov/checkov_deserealizator.py,sha256=_TfAN504MBl17VsSMOymCWaAtQUvS1UKKuDwR2tIx3I,1367
97
- devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/driven_adapters/checkov/checkov_tool.py,sha256=kekssQfHYUftr7x3VIl6pm1ppbmNPERriHSAfDx25fA,7679
97
+ devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/driven_adapters/checkov/checkov_tool.py,sha256=SrEH7SnPLIMjP4OgSXvuntZJFfttgoTVjaitwLCCGhU,7619
98
98
  devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/entry_points/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
99
  devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/entry_points/entry_point_tool.py,sha256=60iaHYZZp5uTngD7a8vsQaQYsTfBzP_kp0xflfPNnk4,305
100
100
  devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
101
- devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/helpers/file_generator_tool.py,sha256=qewN-QIo0tbipeuZNGfwFNlymWQLpIHM1G_Hnedltpk,3007
101
+ devsecops_engine_tools/engine_sast/engine_iac/src/infrastructure/helpers/file_generator_tool.py,sha256=lim8ARYvVT6a2Affqw4QVxhV_wq3aKiGf-2VUskSXII,3083
102
102
  devsecops_engine_tools/engine_sast/engine_secret/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
103
  devsecops_engine_tools/engine_sast/engine_secret/src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
104
104
  devsecops_engine_tools/engine_sast/engine_secret/src/applications/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -138,23 +138,22 @@ devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/des
138
138
  devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/images_gateway.py,sha256=szx-9iO1eSDedr3rw605Mx3jYBEFwRKBM0ts5zImgx0,158
139
139
  devsecops_engine_tools/engine_sca/engine_container/src/domain/model/gateways/tool_gateway.py,sha256=ADZjrl8u8CQ0hWoVhbnHFcjvyUmUeleffwmhtlg8s30,224
140
140
  devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
141
- devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/container_sca_scan.py,sha256=zwlYQSmtn7_ms9x5-Dhr3WTilLM5cXdAyslgWRh5xdc,1635
141
+ devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/container_sca_scan.py,sha256=bJrQr-e_mEQci_cT3a3fWGbCAryX1lFLJbrY8rd-Qg8,3054
142
142
  devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/handle_remote_config_patterns.py,sha256=4wgBTQSDE-C5v01C3Vxzeq0DJKZUSqQ5TVLG7yPZPKs,926
143
- devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/set_input_core.py,sha256=Jw2sjrgRS8kjIFLt2nEBXQpF2-Ncm_ltgc6Q7ZIZKw0,1840
143
+ devsecops_engine_tools/engine_sca/engine_container/src/domain/usecases/set_input_core.py,sha256=DdKyKnLzqswHt619B3s1GTB5u_RyUixCambDkBuu7y4,1806
144
144
  devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
145
145
  devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
146
146
  devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/docker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
147
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/docker/docker_images.py,sha256=tdZeW5KbZcLxSMM37-GdmkLItpRDUlR0eAyew6bI2ts,816
147
+ devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/docker/docker_images.py,sha256=XoF6PtMNIdycuBQbRl7NjBPaqUr80-S8KxV93iEpFNA,1067
148
148
  devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
149
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_cloud_manager_scan.py,sha256=3KyqbuLSFHMAUO5n9ruLMU8nhiP9BuGeXchN9PHW3M0,4369
150
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_deserialize_output.py,sha256=k6j6ajlHFVfKdxIdvWVak0eryhIknT0IyTvyI2e3gz0,2514
149
+ devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_cloud_manager_scan.py,sha256=DUq-cs3DuKpwfKVcu_zCiydLD-OZihbtRiQhVw0Dl1M,3213
150
+ devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/prisma_cloud/prisma_deserialize_output.py,sha256=Q6jPGjAO-oY0YeHZYmmD_in-nA8R6oa4_cBGbNs1oy8,2375
151
151
  devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
152
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/trivy_deserialize_output.py,sha256=v0XU-KJfnt4BFmoLbpc3IE0RxDVsYN5dzftfJiWR2Fs,2169
153
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/trivy_manager_scan.py,sha256=IBd3fOQmHPDeVud54DQtw0x2o4jm31iwRoiBDTpkqdc,4284
152
+ devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/trivy_deserialize_output.py,sha256=LGqnO10Zt-0-TxUW6F1S46jVktlIwxWSYATKSVblCWI,2535
153
+ devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/driven_adapters/trivy_tool/trivy_manager_scan.py,sha256=dAjnif-4CVYWrEpsMeAP97p-vsqtcZooxTBKeW8dzOY,3611
154
154
  devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/entry_points/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
155
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/entry_points/entry_point_tool.py,sha256=BM8XJI_tlFxurdhBz2N5R33z4WGNLN_mkaG2npYBTiM,2212
155
+ devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/entry_points/entry_point_tool.py,sha256=RrpGnDSAL_YnRmONRkOKjWk5JbCOi_vG9dvlz5E_67U,2241
156
156
  devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
157
- devsecops_engine_tools/engine_sca/engine_container/src/infrastructure/helpers/images_scanned.py,sha256=V_wE9maXdGlQbYIe6qVgOqEtiWrh-icd8V4dpWDQrXg,590
158
157
  devsecops_engine_tools/engine_sca/engine_dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
159
158
  devsecops_engine_tools/engine_sca/engine_dependencies/src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
160
159
  devsecops_engine_tools/engine_sca/engine_dependencies/src/applications/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -242,8 +241,8 @@ devsecops_engine_tools/engine_utilities/utils/logger_info.py,sha256=4Mz8Bwlm9Mku
242
241
  devsecops_engine_tools/engine_utilities/utils/name_conversion.py,sha256=ADJrRGaxYSDe0ZRh6VHRf53H4sXPcb-vNP_i81PUn3I,307
243
242
  devsecops_engine_tools/engine_utilities/utils/printers.py,sha256=GAslbWaBpwP3mP6fBsgVl07TTBgcCggQTy8h2M9ibeo,612
244
243
  devsecops_engine_tools/engine_utilities/utils/session_manager.py,sha256=yNtlT-8Legz1sHbGPH8LNYjL-LgDUE0zXG2rYjiab7U,290
245
- devsecops_engine_tools-1.7.16.dist-info/METADATA,sha256=BwG-ipv7ziTvAqeXg3xPytZqTQ0lpI3wch50ZHysRLw,4840
246
- devsecops_engine_tools-1.7.16.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
247
- devsecops_engine_tools-1.7.16.dist-info/entry_points.txt,sha256=9IjXF_7Zpgowq_SY6OSmsA9vZze18a8_AeHwkQVrgKk,131
248
- devsecops_engine_tools-1.7.16.dist-info/top_level.txt,sha256=ge6y0X_xBAU1aG3EMWFtl9djbVyg5BxuSp2r2Lg6EQU,23
249
- devsecops_engine_tools-1.7.16.dist-info/RECORD,,
244
+ devsecops_engine_tools-1.7.18.dist-info/METADATA,sha256=rFH9e75HrUpTxJzgK9S2HKeBnDoqZJC5UEmEvSm-VVQ,4840
245
+ devsecops_engine_tools-1.7.18.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
246
+ devsecops_engine_tools-1.7.18.dist-info/entry_points.txt,sha256=9IjXF_7Zpgowq_SY6OSmsA9vZze18a8_AeHwkQVrgKk,131
247
+ devsecops_engine_tools-1.7.18.dist-info/top_level.txt,sha256=ge6y0X_xBAU1aG3EMWFtl9djbVyg5BxuSp2r2Lg6EQU,23
248
+ devsecops_engine_tools-1.7.18.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- import os
2
-
3
-
4
- class ImagesScanned:
5
- @staticmethod
6
- def get_images_already_scanned(file_name):
7
- """
8
- Create images scanned file if it does not exist and get the images that have already been scanned.
9
- """
10
- scanned_images_file = os.path.join(os.getcwd(), file_name)
11
- # Check if the file exists; if not, create it
12
- if not os.path.exists(scanned_images_file):
13
- open(scanned_images_file, "w").close()
14
- with open(scanned_images_file, "r") as file:
15
- images_scanned = file.read().splitlines()
16
- return images_scanned