primitive 0.2.70__tar.gz → 0.2.72__tar.gz

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 primitive might be problematic. Click here for more details.

Files changed (137) hide show
  1. {primitive-0.2.70 → primitive-0.2.72}/.vscode/settings.json +1 -0
  2. {primitive-0.2.70 → primitive-0.2.72}/PKG-INFO +1 -1
  3. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/__about__.py +1 -1
  4. primitive-0.2.72/src/primitive/agent/pxe.py +71 -0
  5. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/agent/runner.py +2 -25
  6. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/hardware/actions.py +13 -2
  7. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/messaging/provider.py +1 -0
  8. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/monitor/actions.py +1 -1
  9. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/network/actions.py +6 -10
  10. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/network/ssh.py +16 -7
  11. primitive-0.2.72/src/primitive/operating_systems/actions.py +473 -0
  12. primitive-0.2.72/src/primitive/operating_systems/commands.py +246 -0
  13. primitive-0.2.72/testing_containers/README.md +21 -0
  14. {primitive-0.2.70 → primitive-0.2.72}/testing_containers/fedora.Containerfile +4 -3
  15. {primitive-0.2.70 → primitive-0.2.72}/testing_containers/ubuntu.Containerfile +4 -3
  16. primitive-0.2.70/src/primitive/operating_systems/actions.py +0 -260
  17. primitive-0.2.70/src/primitive/operating_systems/commands.py +0 -268
  18. primitive-0.2.70/testing_containers/README.md +0 -13
  19. {primitive-0.2.70 → primitive-0.2.72}/.git-hooks/pre-commit +0 -0
  20. {primitive-0.2.70 → primitive-0.2.72}/.gitattributes +0 -0
  21. {primitive-0.2.70 → primitive-0.2.72}/.github/workflows/lint.yml +0 -0
  22. {primitive-0.2.70 → primitive-0.2.72}/.github/workflows/publish.yml +0 -0
  23. {primitive-0.2.70 → primitive-0.2.72}/.github/workflows/pyright.yml +0 -0
  24. {primitive-0.2.70 → primitive-0.2.72}/.gitignore +0 -0
  25. {primitive-0.2.70 → primitive-0.2.72}/.vscode/extensions.json +0 -0
  26. {primitive-0.2.70 → primitive-0.2.72}/LICENSE.txt +0 -0
  27. {primitive-0.2.70 → primitive-0.2.72}/Makefile +0 -0
  28. {primitive-0.2.70 → primitive-0.2.72}/README.md +0 -0
  29. {primitive-0.2.70 → primitive-0.2.72}/linux setup.md +0 -0
  30. {primitive-0.2.70 → primitive-0.2.72}/pyproject.toml +0 -0
  31. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/__init__.py +0 -0
  32. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/agent/__init__.py +0 -0
  33. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/agent/actions.py +0 -0
  34. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/agent/commands.py +0 -0
  35. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/agent/uploader.py +0 -0
  36. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/auth/__init__.py +0 -0
  37. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/auth/actions.py +0 -0
  38. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/auth/commands.py +0 -0
  39. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/auth/graphql/__init__.py +0 -0
  40. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/auth/graphql/queries.py +0 -0
  41. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/cli.py +0 -0
  42. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/client.py +0 -0
  43. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/daemons/__init__.py +0 -0
  44. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/daemons/actions.py +0 -0
  45. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/daemons/commands.py +0 -0
  46. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/daemons/launch_agents.py +0 -0
  47. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/daemons/launch_service.py +0 -0
  48. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/daemons/ui.py +0 -0
  49. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/exec/__init__.py +0 -0
  50. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/exec/actions.py +0 -0
  51. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/exec/commands.py +0 -0
  52. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/exec/interactive.py +0 -0
  53. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/files/__init__.py +0 -0
  54. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/files/actions.py +0 -0
  55. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/files/commands.py +0 -0
  56. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/files/graphql/__init__.py +0 -0
  57. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/files/graphql/fragments.py +0 -0
  58. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/files/graphql/mutations.py +0 -0
  59. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/files/graphql/queries.py +0 -0
  60. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/files/ui.py +0 -0
  61. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/git/__init__.py +0 -0
  62. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/git/actions.py +0 -0
  63. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/git/commands.py +0 -0
  64. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/git/graphql/__init__.py +0 -0
  65. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/git/graphql/queries.py +0 -0
  66. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/graphql/__init__.py +0 -0
  67. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/graphql/relay.py +0 -0
  68. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/graphql/sdk.py +0 -0
  69. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/graphql/utility_fragments.py +0 -0
  70. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/hardware/__init__.py +0 -0
  71. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/hardware/android.py +0 -0
  72. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/hardware/commands.py +0 -0
  73. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/hardware/graphql/__init__.py +0 -0
  74. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/hardware/graphql/fragments.py +0 -0
  75. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/hardware/graphql/mutations.py +0 -0
  76. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/hardware/graphql/queries.py +0 -0
  77. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/hardware/ui.py +0 -0
  78. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/jobs/__init__.py +0 -0
  79. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/jobs/actions.py +0 -0
  80. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/jobs/commands.py +0 -0
  81. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/jobs/graphql/__init__.py +0 -0
  82. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/jobs/graphql/fragments.py +0 -0
  83. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/jobs/graphql/mutations.py +0 -0
  84. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/jobs/graphql/queries.py +0 -0
  85. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/messaging/__init__.py +0 -0
  86. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/monitor/commands.py +0 -0
  87. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/network/__init__.py +0 -0
  88. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/network/commands.py +0 -0
  89. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/network/redfish.py +0 -0
  90. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/network/ui.py +0 -0
  91. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/operating_systems/__init__.py +0 -0
  92. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/operating_systems/graphql/__init__.py +0 -0
  93. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/operating_systems/graphql/mutations.py +0 -0
  94. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/operating_systems/graphql/queries.py +0 -0
  95. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/organizations/__init__.py +0 -0
  96. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/organizations/actions.py +0 -0
  97. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/organizations/commands.py +0 -0
  98. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/organizations/graphql/__init__.py +0 -0
  99. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/organizations/graphql/fragments.py +0 -0
  100. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/organizations/graphql/mutations.py +0 -0
  101. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/organizations/graphql/queries.py +0 -0
  102. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/projects/__init__.py +0 -0
  103. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/projects/actions.py +0 -0
  104. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/projects/commands.py +0 -0
  105. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/projects/graphql/__init__.py +0 -0
  106. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/projects/graphql/fragments.py +0 -0
  107. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/projects/graphql/mutations.py +0 -0
  108. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/projects/graphql/queries.py +0 -0
  109. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/provisioning/__init__.py +0 -0
  110. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/provisioning/actions.py +0 -0
  111. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/provisioning/graphql/__init__.py +0 -0
  112. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/provisioning/graphql/queries.py +0 -0
  113. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/reservations/__init__.py +0 -0
  114. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/reservations/actions.py +0 -0
  115. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/reservations/commands.py +0 -0
  116. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/reservations/graphql/__init__.py +0 -0
  117. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/reservations/graphql/fragments.py +0 -0
  118. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/reservations/graphql/mutations.py +0 -0
  119. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/reservations/graphql/queries.py +0 -0
  120. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/__init__.py +0 -0
  121. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/actions.py +0 -0
  122. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/auth.py +0 -0
  123. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/cache.py +0 -0
  124. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/checksums.py +0 -0
  125. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/chunk_size.py +0 -0
  126. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/config.py +0 -0
  127. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/daemons.py +0 -0
  128. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/exceptions.py +0 -0
  129. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/logging.py +0 -0
  130. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/memory_size.py +0 -0
  131. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/printer.py +0 -0
  132. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/psutil.py +0 -0
  133. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/shell.py +0 -0
  134. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/text.py +0 -0
  135. {primitive-0.2.70 → primitive-0.2.72}/src/primitive/utils/x509.py +0 -0
  136. {primitive-0.2.70 → primitive-0.2.72}/tests/__init__.py +0 -0
  137. {primitive-0.2.70 → primitive-0.2.72}/uv.lock +0 -0
@@ -3,6 +3,7 @@
3
3
  "ajob",
4
4
  "cafile",
5
5
  "Checkin",
6
+ "efibootmgr",
6
7
  "loguru",
7
8
  "machdep",
8
9
  "Mbit",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: primitive
3
- Version: 0.2.70
3
+ Version: 0.2.72
4
4
  Project-URL: Documentation, https://github.com//primitivecorp/primitive-cli#readme
5
5
  Project-URL: Issues, https://github.com//primitivecorp/primitive-cli/issues
6
6
  Project-URL: Source, https://github.com//primitivecorp/primitive-cli
@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2025-present Dylan Stein <dylan@primitive.tech>
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
- __version__ = "0.2.70"
4
+ __version__ = "0.2.72"
@@ -0,0 +1,71 @@
1
+ from loguru import logger
2
+
3
+ from primitive.network.redfish import RedfishClient
4
+ from primitive.network.ssh import test_ssh_connection, run_command
5
+
6
+
7
+ def pxe_boot_via_redfish(target_hardware_secret: dict):
8
+ bmc_host = target_hardware_secret.get("bmcHostname", None)
9
+ bmc_username = target_hardware_secret.get("bmcUsername", None)
10
+ bmc_password = target_hardware_secret.get("bmcPassword", "")
11
+
12
+ if bmc_host is None:
13
+ logger.error(
14
+ "No BMC host found in target hardware secret for out-of-band power cycle"
15
+ )
16
+ return True
17
+ if bmc_username is None:
18
+ logger.error(
19
+ "No BMC username found in target hardware secret for out-of-band power cycle"
20
+ )
21
+ return True
22
+
23
+ redfish = RedfishClient(host=bmc_host, username=bmc_username, password=bmc_password)
24
+ redfish.update_boot_options(
25
+ system_id="1",
26
+ boot_source_override_target="Pxe",
27
+ boot_source_override_enabled="Once",
28
+ boot_source_override_mode="UEFI",
29
+ )
30
+ redfish.compute_system_reset(system_id="1", reset_type="ForceRestart")
31
+
32
+
33
+ def pxe_boot_via_efibootmgr(target_hardware_secret: dict):
34
+ run_command(
35
+ hostname=target_hardware_secret.get("hostname"),
36
+ username=target_hardware_secret.get("username"),
37
+ password=target_hardware_secret.get("password"),
38
+ command="sudo efibootmgr -n $(efibootmgr | awk '/PXE IPV4/ {print substr($1,5,4)}' | head -n1 || efibootmgr | awk '/ubuntu/ {print substr($1,5,4)}' | head -n1) && sudo reboot",
39
+ port=22,
40
+ )
41
+
42
+
43
+ def pxe_boot(target_hardware_secret: dict) -> bool:
44
+ redfish_available = False
45
+ ssh_available = False
46
+
47
+ if target_hardware_secret.get("bmcHostname", None):
48
+ redfish_available = True
49
+ else:
50
+ logger.info(
51
+ "No BMC credentials found, skipping Redfish PXE boot method. Checking efiboot method."
52
+ )
53
+
54
+ ssh_available = test_ssh_connection(
55
+ hostname=target_hardware_secret.get("hostname"),
56
+ username=target_hardware_secret.get("username"),
57
+ password=target_hardware_secret.get("password"),
58
+ port=22,
59
+ )
60
+
61
+ if redfish_available:
62
+ pxe_boot_via_redfish(target_hardware_secret=target_hardware_secret)
63
+ return True
64
+ elif ssh_available:
65
+ pxe_boot_via_efibootmgr(target_hardware_secret=target_hardware_secret)
66
+ return True
67
+ else:
68
+ logger.error(
69
+ "No available method to PXE boot target hardware. Missing BMC credentials and SSH is not available."
70
+ )
71
+ return False
@@ -10,6 +10,7 @@ from datetime import datetime, timezone
10
10
 
11
11
  from loguru import logger
12
12
 
13
+ from primitive.agent.pxe import pxe_boot
13
14
  from primitive.network.ssh import wait_for_ssh
14
15
  from primitive.utils.cache import get_artifacts_cache, get_logs_cache, get_sources_cache
15
16
  from primitive.utils.logging import fmt, log_context
@@ -287,33 +288,9 @@ class Runner:
287
288
 
288
289
  if cmd == "pxeboot":
289
290
  logger.info("Setting next boot to PXE and rebooting")
290
- from primitive.network.redfish import RedfishClient
291
-
292
- bmc_host = self.target_hardware_secret.get("bmcHostname", None)
293
- bmc_username = self.target_hardware_secret.get("bmcUsername", None)
294
- bmc_password = self.target_hardware_secret.get("bmcPassword", "")
295
291
 
296
- if bmc_host is None:
297
- logger.error(
298
- "No BMC host found in target hardware secret for out-of-band power cycle"
299
- )
300
- return True
301
- if bmc_username is None:
302
- logger.error(
303
- "No BMC username found in target hardware secret for out-of-band power cycle"
304
- )
305
- return True
292
+ pxe_boot(target_hardware_secret=self.target_hardware_secret)
306
293
 
307
- redfish = RedfishClient(
308
- host=bmc_host, username=bmc_username, password=bmc_password
309
- )
310
- redfish.update_boot_options(
311
- system_id="1",
312
- boot_source_override_target="Pxe",
313
- boot_source_override_enabled="Once",
314
- boot_source_override_mode="UEFI",
315
- )
316
- redfish.compute_system_reset(system_id="1", reset_type="ForceRestart")
317
294
  if self.target_hardware_id:
318
295
  await self.primitive.hardware.aupdate_hardware(
319
296
  hardware_id=self.target_hardware_id,
@@ -421,7 +421,10 @@ class Hardware(BaseAction):
421
421
  def _get_ubuntu_installed_packages(self):
422
422
  try:
423
423
  lines = (
424
- subprocess.check_output(["apt", "list", "--installed"])
424
+ subprocess.check_output(
425
+ ["apt", "list", "--installed"],
426
+ stderr=subprocess.DEVNULL,
427
+ )
425
428
  .decode("utf-8")
426
429
  .strip()
427
430
  .split("\n")
@@ -793,7 +796,7 @@ class Hardware(BaseAction):
793
796
  if slug is not None:
794
797
  filters["slug"] = {"exact": slug}
795
798
  if id is not None:
796
- filters["id"] = {"exact": id}
799
+ filters["id"] = id
797
800
  # if nested_children is True:
798
801
  # filters["hasParent"] = {"exact": False}
799
802
 
@@ -1206,3 +1209,11 @@ class Hardware(BaseAction):
1206
1209
  logger.info(message)
1207
1210
 
1208
1211
  return result
1212
+
1213
+ def push_own_system_info(self):
1214
+ if self.primitive.messaging.ready:
1215
+ message = {"system_info": self.primitive.hardware.get_system_info()}
1216
+ self.primitive.messaging.send_message(
1217
+ message_type=MESSAGE_TYPES.SYSTEM_INFO,
1218
+ message=message,
1219
+ )
@@ -27,6 +27,7 @@ CELERY_TASK_NAME = "hardware.tasks.task_receive_hardware_message"
27
27
 
28
28
  class MESSAGE_TYPES(enum.Enum):
29
29
  CHECK_IN = "CHECK_IN"
30
+ SYSTEM_INFO = "SYSTEM_INFO"
30
31
  METRICS = "METRICS"
31
32
  SWITCH_AND_INTERFACES_INFO = "SWITCH_AND_INTERFACES_INFO"
32
33
  OWN_NETWORK_INTERFACES = "OWN_NETWORK_INTERFACES"
@@ -94,7 +94,7 @@ class Monitor(BaseAction):
94
94
  if hardware.get("isController", False):
95
95
  self.primitive.hardware.get_and_set_switch_info()
96
96
  self.primitive.network.push_switch_and_interfaces_info()
97
- self.primitive.network.push_own_network_interfaces()
97
+ self.primitive.hardware.push_own_system_info()
98
98
  self.primitive.hardware._sync_children(hardware=hardware)
99
99
 
100
100
  sleep_amount = 5
@@ -8,6 +8,7 @@ from paramiko import SSHClient
8
8
  from typing import TypedDict
9
9
  import re
10
10
 
11
+ from primitive.hardware.actions import does_executable_exist
11
12
  from primitive.messaging.provider import MESSAGE_TYPES
12
13
  from primitive.utils.actions import BaseAction
13
14
 
@@ -372,6 +373,9 @@ class Network(BaseAction):
372
373
  return ip_to_mac_address_info
373
374
 
374
375
  def get_ip_arp_table_via_ip_command(self):
376
+ if does_executable_exist("ip") is False:
377
+ return []
378
+
375
379
  command = "ip --json neigh show"
376
380
  ip_result = None
377
381
  with Popen(command.split(" "), stdout=PIPE) as process:
@@ -458,6 +462,7 @@ class Network(BaseAction):
458
462
  return False
459
463
 
460
464
  def push_switch_and_interfaces_info(self, interfaces_info: dict | None = None):
465
+ logger.debug("Pushing switch and interfaces info")
461
466
  if self.primitive.messaging.ready and self.switch_connection_info is not None:
462
467
  switch_info = self.get_switch_info()
463
468
  interfaces_info = interfaces_info or self.get_interfaces_info()
@@ -473,13 +478,4 @@ class Network(BaseAction):
473
478
  message_type=MESSAGE_TYPES.SWITCH_AND_INTERFACES_INFO,
474
479
  message=message,
475
480
  )
476
-
477
- def push_own_network_interfaces(self):
478
- if self.primitive.messaging.ready:
479
- message = {
480
- "network_interfaces": self.primitive.hardware._get_network_interfaces()
481
- }
482
- self.primitive.messaging.send_message(
483
- message_type=MESSAGE_TYPES.OWN_NETWORK_INTERFACES,
484
- message=message,
485
- )
481
+ logger.debug("Switch and interfaces info pushed")
@@ -27,7 +27,13 @@ def test_ssh_connection(hostname, username, password=None, key_filename=None, po
27
27
  try:
28
28
  if password:
29
29
  ssh_client.connect(
30
- hostname=hostname, port=port, username=username, password=password
30
+ hostname=hostname,
31
+ port=port,
32
+ username=username,
33
+ password=password,
34
+ banner_timeout=60,
35
+ timeout=60,
36
+ auth_timeout=60,
31
37
  )
32
38
  elif key_filename:
33
39
  ssh_client.connect(
@@ -35,26 +41,29 @@ def test_ssh_connection(hostname, username, password=None, key_filename=None, po
35
41
  port=port,
36
42
  username=username,
37
43
  key_filename=key_filename,
44
+ banner_timeout=60,
45
+ timeout=60,
46
+ auth_timeout=60,
38
47
  )
39
48
  else:
40
- print(
49
+ logger.error(
41
50
  "Error: Either password or key_filename must be provided for authentication."
42
51
  )
43
52
  return False
44
53
 
45
- print(f"Successfully connected to {hostname} as {username}")
54
+ logger.info(f"Successfully connected to {hostname} as {username}")
46
55
  return True
47
56
  except paramiko.AuthenticationException:
48
- print(f"Authentication failed for {username} on {hostname}")
57
+ logger.debug(f"Authentication failed for {username} on {hostname}")
49
58
  return False
50
59
  except paramiko.SSHException as exception:
51
- print(f"SSH error connecting to {hostname}: {exception}")
60
+ logger.debug(f"SSH error connecting to {hostname}: {exception}")
52
61
  return False
53
62
  except socket.error as exception:
54
- print(f"Socket error connecting to {hostname}: {exception}")
63
+ logger.debug(f"Socket error connecting to {hostname}: {exception}")
55
64
  return False
56
65
  except Exception as exception:
57
- print(f"An unexpected error occurred: {exception}")
66
+ logger.debug(f"An unexpected error occurred: {exception}")
58
67
  return False
59
68
  finally:
60
69
  ssh_client.close()