osism 0.20250701.0__py3-none-any.whl → 0.20250804.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.
osism/utils/ssh.py ADDED
@@ -0,0 +1,250 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+
3
+ import os
4
+ import subprocess
5
+ from typing import List, Optional
6
+ from loguru import logger
7
+
8
+ from osism import utils
9
+
10
+
11
+ def get_host_identifiers(hostname: str) -> List[str]:
12
+ """
13
+ Get all possible host identifiers for SSH known_hosts cleanup.
14
+
15
+ This includes the hostname itself and its resolved IP address
16
+ (both via DNS and Netbox fallback if available).
17
+
18
+ Args:
19
+ hostname: The hostname to get identifiers for
20
+
21
+ Returns:
22
+ List of unique host identifiers (hostname, IPs)
23
+ """
24
+ identifiers = [hostname]
25
+
26
+ # Try DNS resolution first
27
+ try:
28
+ import socket
29
+
30
+ ip_address = socket.gethostbyname(hostname)
31
+ if ip_address and ip_address not in identifiers:
32
+ identifiers.append(ip_address)
33
+ logger.debug(f"Resolved hostname {hostname} to {ip_address} via DNS")
34
+ except socket.gaierror as e:
35
+ logger.debug(f"DNS resolution failed for {hostname}: {e}")
36
+
37
+ # Try Netbox fallback if available
38
+ if utils.nb:
39
+ try:
40
+ device = utils.nb.dcim.devices.get(name=hostname)
41
+ if device and device.primary_ip4:
42
+ ip_address = str(device.primary_ip4.address).split("/")[0]
43
+ if ip_address and ip_address not in identifiers:
44
+ identifiers.append(ip_address)
45
+ logger.debug(
46
+ f"Found primary IPv4 for {hostname} in Netbox: {ip_address}"
47
+ )
48
+ except Exception as e:
49
+ logger.debug(f"Error querying Netbox for {hostname}: {e}")
50
+
51
+ return identifiers
52
+
53
+
54
+ def remove_known_hosts_entries(
55
+ hostname: str, known_hosts_path: str = "/share/known_hosts"
56
+ ) -> bool:
57
+ """
58
+ Remove SSH known_hosts entries for a given hostname and its IP addresses.
59
+
60
+ This function safely removes entries from the SSH known_hosts file for both
61
+ the hostname and any resolved IP addresses (DNS + Netbox fallback).
62
+
63
+ Args:
64
+ hostname: The hostname to remove entries for
65
+ known_hosts_path: Path to the SSH known_hosts file (default: /share/known_hosts)
66
+
67
+ Returns:
68
+ True if cleanup was successful, False otherwise
69
+ """
70
+ if not hostname or not hostname.strip():
71
+ logger.warning("Empty hostname provided for SSH known_hosts cleanup")
72
+ return False
73
+
74
+ if not os.path.exists(known_hosts_path):
75
+ logger.debug(f"SSH known_hosts file does not exist: {known_hosts_path}")
76
+ return True
77
+
78
+ # Assume ssh-keygen is available (it's a standard SSH tool)
79
+
80
+ # Get all possible host identifiers
81
+ try:
82
+ identifiers = get_host_identifiers(hostname)
83
+ if not identifiers:
84
+ logger.warning(f"No host identifiers found for {hostname}")
85
+ return False
86
+
87
+ logger.info(f"Cleaning SSH known_hosts entries for {hostname}: {identifiers}")
88
+ except Exception as e:
89
+ logger.error(f"Error getting host identifiers for {hostname}: {e}")
90
+ return False
91
+
92
+ success = True
93
+ entries_removed = 0
94
+
95
+ for identifier in identifiers:
96
+ if not identifier or not identifier.strip():
97
+ logger.debug("Skipping empty identifier")
98
+ continue
99
+
100
+ try:
101
+ # Use ssh-keygen to remove entries safely
102
+ # The -R option removes all keys for the specified host
103
+ result = subprocess.run(
104
+ ["ssh-keygen", "-R", identifier, "-f", known_hosts_path],
105
+ capture_output=True,
106
+ text=True,
107
+ timeout=30, # Increased timeout for safety
108
+ )
109
+
110
+ if result.returncode == 0:
111
+ # ssh-keygen returns 0 even if no entries were found
112
+ # Check stderr for messages about entries being updated
113
+ stderr_lower = result.stderr.lower()
114
+ if "updated" in stderr_lower or identifier in stderr_lower:
115
+ entries_removed += 1
116
+ logger.debug(f"Removed SSH known_hosts entries for {identifier}")
117
+ else:
118
+ logger.debug(f"No SSH known_hosts entries found for {identifier}")
119
+ else:
120
+ # Log stderr for debugging but don't fail entirely
121
+ logger.warning(
122
+ f"ssh-keygen returned non-zero exit code for {identifier}: {result.stderr.strip()}"
123
+ )
124
+
125
+ except subprocess.TimeoutExpired:
126
+ logger.error(
127
+ f"Timeout while removing SSH known_hosts entries for {identifier}"
128
+ )
129
+ success = False
130
+ except subprocess.CalledProcessError as e:
131
+ logger.error(
132
+ f"Error removing SSH known_hosts entries for {identifier}: {e}"
133
+ )
134
+ success = False
135
+ except Exception as e:
136
+ logger.error(
137
+ f"Unexpected error removing SSH known_hosts entries for {identifier}: {e}"
138
+ )
139
+ success = False
140
+
141
+ if entries_removed > 0:
142
+ logger.info(
143
+ f"Successfully cleaned {entries_removed} SSH known_hosts entries for {hostname}"
144
+ )
145
+ else:
146
+ logger.debug(f"No SSH known_hosts entries found to clean for {hostname}")
147
+
148
+ return success
149
+
150
+
151
+ def backup_known_hosts(
152
+ known_hosts_path: str = "/share/known_hosts",
153
+ ) -> Optional[str]:
154
+ """
155
+ Create a backup of the SSH known_hosts file before making changes.
156
+
157
+ Args:
158
+ known_hosts_path: Path to the SSH known_hosts file
159
+
160
+ Returns:
161
+ Path to the backup file if successful, None otherwise
162
+ """
163
+ if not known_hosts_path or not known_hosts_path.strip():
164
+ logger.warning("Empty known_hosts path provided for backup")
165
+ return None
166
+
167
+ if not os.path.exists(known_hosts_path):
168
+ logger.debug(
169
+ f"SSH known_hosts file does not exist, no backup needed: {known_hosts_path}"
170
+ )
171
+ return None
172
+
173
+ try:
174
+ # Check if file is readable
175
+ if not os.access(known_hosts_path, os.R_OK):
176
+ logger.warning(f"SSH known_hosts file is not readable: {known_hosts_path}")
177
+ return None
178
+
179
+ # Create backup with timestamp
180
+ import datetime
181
+
182
+ timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
183
+ backup_path = f"{known_hosts_path}.backup_{timestamp}"
184
+
185
+ # Ensure backup directory exists and is writable
186
+ backup_dir = os.path.dirname(backup_path)
187
+ if not os.path.exists(backup_dir):
188
+ logger.warning(f"Backup directory does not exist: {backup_dir}")
189
+ return None
190
+
191
+ if not os.access(backup_dir, os.W_OK):
192
+ logger.warning(f"Backup directory is not writable: {backup_dir}")
193
+ return None
194
+
195
+ # Copy the file
196
+ import shutil
197
+
198
+ shutil.copy2(known_hosts_path, backup_path)
199
+
200
+ # Verify backup was created successfully
201
+ if os.path.exists(backup_path) and os.path.getsize(backup_path) > 0:
202
+ logger.debug(f"Created SSH known_hosts backup: {backup_path}")
203
+ return backup_path
204
+ else:
205
+ logger.warning(f"Backup file was not created properly: {backup_path}")
206
+ return None
207
+
208
+ except PermissionError as e:
209
+ logger.warning(f"Permission denied creating SSH known_hosts backup: {e}")
210
+ return None
211
+ except OSError as e:
212
+ logger.warning(f"OS error creating SSH known_hosts backup: {e}")
213
+ return None
214
+ except Exception as e:
215
+ logger.warning(f"Unexpected error creating SSH known_hosts backup: {e}")
216
+ return None
217
+
218
+
219
+ def cleanup_ssh_known_hosts_for_node(hostname: str, create_backup: bool = True) -> bool:
220
+ """
221
+ High-level function to clean up SSH known_hosts entries for a node.
222
+
223
+ This is the main function that should be called from reset/undeploy commands.
224
+ It optionally creates a backup and then removes all SSH known_hosts entries
225
+ for the specified hostname and its IP addresses.
226
+
227
+ Args:
228
+ hostname: The hostname/node name to clean up entries for
229
+ create_backup: Whether to create a backup before cleanup (default: True)
230
+
231
+ Returns:
232
+ True if cleanup was successful, False otherwise
233
+ """
234
+ known_hosts_path = "/share/known_hosts"
235
+
236
+ try:
237
+ # Create backup if requested
238
+ if create_backup:
239
+ backup_path = backup_known_hosts(known_hosts_path)
240
+ if backup_path:
241
+ logger.debug(f"SSH known_hosts backup created: {backup_path}")
242
+
243
+ # Perform the cleanup
244
+ success = remove_known_hosts_entries(hostname, known_hosts_path)
245
+
246
+ return success
247
+
248
+ except Exception as e:
249
+ logger.error(f"Error during SSH known_hosts cleanup for {hostname}: {e}")
250
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: osism
3
- Version: 0.20250701.0
3
+ Version: 0.20250804.0
4
4
  Summary: OSISM manager interface
5
5
  Home-page: https://github.com/osism/python-osism
6
6
  Author: OSISM GmbH
@@ -23,7 +23,7 @@ Description-Content-Type: text/markdown
23
23
  License-File: LICENSE
24
24
  License-File: AUTHORS
25
25
  Requires-Dist: ClusterShell==1.9.3
26
- Requires-Dist: GitPython==3.1.44
26
+ Requires-Dist: GitPython==3.1.45
27
27
  Requires-Dist: Jinja2==3.1.6
28
28
  Requires-Dist: PyYAML==6.0.2
29
29
  Requires-Dist: ara==1.7.2
@@ -32,7 +32,7 @@ Requires-Dist: cliff==4.10.0
32
32
  Requires-Dist: deepdiff==8.5.0
33
33
  Requires-Dist: docker==7.1.0
34
34
  Requires-Dist: dtrack-auditor==1.5.0
35
- Requires-Dist: fastapi==0.115.14
35
+ Requires-Dist: fastapi==0.116.1
36
36
  Requires-Dist: flower==2.0.1
37
37
  Requires-Dist: hiredis==3.2.1
38
38
  Requires-Dist: jc==1.25.5
@@ -50,15 +50,15 @@ Requires-Dist: pytest-testinfra==10.2.2
50
50
  Requires-Dist: python-dateutil==2.9.0.post0
51
51
  Requires-Dist: setuptools==80.9.0
52
52
  Requires-Dist: sqlmodel==0.0.24
53
- Requires-Dist: sushy==5.6.0
53
+ Requires-Dist: sushy==5.7.0
54
54
  Requires-Dist: tabulate==0.9.0
55
- Requires-Dist: transitions==0.9.2
55
+ Requires-Dist: transitions==0.9.3
56
56
  Requires-Dist: uvicorn[standard]==0.35.0
57
57
  Requires-Dist: validators==0.35.0
58
58
  Requires-Dist: watchdog==6.0.0
59
59
  Provides-Extra: ansible
60
60
  Requires-Dist: ansible-runner==2.4.1; extra == "ansible"
61
- Requires-Dist: ansible-core==2.18.6; extra == "ansible"
61
+ Requires-Dist: ansible-core==2.19.0; extra == "ansible"
62
62
  Provides-Extra: openstack-image-manager
63
63
  Requires-Dist: openstack-image-manager==0.20250508.0; extra == "openstack-image-manager"
64
64
  Dynamic: author
@@ -1,26 +1,27 @@
1
1
  osism/__init__.py,sha256=1UiNTBus0V0f2AbZQzAtVtu6zkfCCrw0OTq--NwFAqY,341
2
2
  osism/__main__.py,sha256=ILe4gu61xEISiBsxanqTQIdSkV-YhpZXTRlguCYyssk,141
3
- osism/api.py,sha256=3kEfPJtPwuWD8luDNnEFRx3nEsUY5AeWnmjd4A5ii-A,11079
3
+ osism/api.py,sha256=7BKVedr3aK8QSRf4ZI1WpraYivibimx-SqVKVAzD6bw,11070
4
4
  osism/main.py,sha256=Dt2-9sLXcS-Ny4DAz7hrha-KRc7zd7BFUTRdfs_X8z4,893
5
5
  osism/settings.py,sha256=IUbUo8kru8TeiMAnnil5oHwd8SqbkPCY401dVONMygo,1885
6
6
  osism/commands/__init__.py,sha256=Ag4wX_DCgXRdoLn6t069jqb3DdRylsX2nyYkiyCx4uk,456
7
7
  osism/commands/apply.py,sha256=GWUccZAXlgkPYqylrCmdWcj8FCkDsPEipIIG937MeII,16833
8
- osism/commands/baremetal.py,sha256=yxCb0UwBfERinoGvlD9bvsGPEdDcHhq48Mn6u5b2aM8,12037
9
- osism/commands/compose.py,sha256=iqzG7mS9E1VWaLNN6yQowjOqiHn3BMdj-yfXb3Dc4Ok,1200
8
+ osism/commands/baremetal.py,sha256=jejkH4oA9SQsjivABBIKuqegTv4G7FqRsIc7soAMj08,19207
9
+ osism/commands/compose.py,sha256=76HL9wzTJ7bFPhZk-uyfWq0n6Z74lOHn4RE0zzkHgYE,1241
10
10
  osism/commands/compute.py,sha256=cgqXWJa5wAvn-7e3FWCgX6hie_aK0yrKRkcNzjLXwDY,25799
11
11
  osism/commands/configuration.py,sha256=sPe8b0dVKFRbr30xoeVdAnHbGwCwgUh0xa_Vzv5pSQQ,954
12
- osism/commands/console.py,sha256=8BPz1hio5Wi6kONVAWFuSqkDRrMcLEYeFIY8dbtN6e4,3218
13
- osism/commands/container.py,sha256=Fku2GaCM3Idq_FxExUtNqjrEM0XYjpVvXmueSVO8S_c,1601
12
+ osism/commands/console.py,sha256=0BSDKewPGAwWAJwi_WrFZ_dRMbMQzbG6IS_0gVi88J8,6276
13
+ osism/commands/container.py,sha256=jHk5A0PXBzHGIm-1d5HQZI_POANAq7An1lZGRbqBvr0,1642
14
14
  osism/commands/get.py,sha256=ryytjtXWmlMV0NucP5tGkMZu0nIlC4xVtjRk4iMZ06c,8967
15
- osism/commands/log.py,sha256=2IpYuosC7FZwwLvM8HmKSU1NRNIelVVYzqjjVMCrOJk,4072
16
- osism/commands/manage.py,sha256=uzfmt3R0PJ4HxUw_V945pN0FbKb3zhyiBuD9br1ORYE,23149
17
- osism/commands/netbox.py,sha256=e65P0kWrjTLw2T9HZthxjDTIRa-KAHgSSJAlvVef7n4,7345
15
+ osism/commands/log.py,sha256=QnnTTNiAoa8oj4kDOcggh0QrRAD6onxcEpLXBy7CvDg,4113
16
+ osism/commands/manage.py,sha256=FaO9dbYjNHYanS98-zC498bx26oU8E3loxCczH9mfKI,12751
17
+ osism/commands/netbox.py,sha256=K8kP-OA1A65U-Cjrtn2lKxQKf9IdCcsOjQbkBaMSI7Y,8272
18
18
  osism/commands/noset.py,sha256=7zDFuFMyNpo7DUOKcNiYV8nodtdMOYFp5LDPcuJhlZ8,1481
19
19
  osism/commands/reconciler.py,sha256=ubQfX8j13s3NuMKnT0Lt6O-szf7Z1V02AfsMQFHmO74,2209
20
20
  osism/commands/redfish.py,sha256=oBfxd5UBX4ED8XulEuIYziIYQqTvUKpKfcdGyg_AoiI,8431
21
21
  osism/commands/server.py,sha256=avmoOv5rjOi-fN2A-27cPwOtiy2Q2j6UFtCh3QrfWAI,7512
22
22
  osism/commands/service.py,sha256=A1lgAlGeCJpbFFqF55DRWPcCirIgpU0dzjzVLZ0mz3k,2649
23
23
  osism/commands/set.py,sha256=xLBi2DzbVQo2jb3-cOIE9In5UB3vFxquQJkDN-EsfhM,1425
24
+ osism/commands/sonic.py,sha256=H_KyMVUgXhiCjZ3T1VW9IzM-8yiRjhgj-JzzvgY9mSE,43622
24
25
  osism/commands/status.py,sha256=X-Rcj-XuNPDBoxsGkf96NswwpmTognxz1V6E2NX2ZgY,1997
25
26
  osism/commands/sync.py,sha256=jOg-g8NmVOkXBI6rOuiOx2WgUJc1PplLAAAwc0VuIfw,1919
26
27
  osism/commands/task.py,sha256=mwJJ7a71Lw3o_FX7j3rR0-NbPdPwMDOjbOAiiXE4uGc,543
@@ -34,37 +35,38 @@ osism/data/enums.py,sha256=gItIjOK6xWuOZSkMxpMdYLRyt4ezyhzkqA7BGiah2o0,10030
34
35
  osism/data/playbooks.py,sha256=M3T3ajV-8Lt-orsRO3jAoukhaoYFr4EZ2dzYXQjt1kg,728
35
36
  osism/services/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
36
37
  osism/services/listener.py,sha256=Vf8LOZkHzlspm40BZ1az3o1O_ar34_i6C83p-D8KzzM,9783
37
- osism/tasks/__init__.py,sha256=kocG0q2bARhkkSjMBH2xWdFUIJodesdh5qVsV_DqZmE,7148
38
- osism/tasks/ansible.py,sha256=_2zrHwynwwEv9nDnX-LbNCzcwy9dTUGo_yyutt34HyQ,1346
38
+ osism/tasks/__init__.py,sha256=iAUs-ttUMw1nZElL631sT1ke29RvTjQjlhWPl_kGrEw,9003
39
+ osism/tasks/ansible.py,sha256=-gUe6uZFhPLI3DGZHlpQlghuDKpp4Drn5IEctlV6Sv8,1300
39
40
  osism/tasks/ceph.py,sha256=eIQkah3Kj4INtOkF9kTjHbXJ3_J2lg48EWJKfHc-UYw,615
40
41
  osism/tasks/conductor.py,sha256=WBLsoPtr0iGUzRGERs0Xt7CMYrnHQVEwNV9qXBssI3s,274
41
42
  osism/tasks/kolla.py,sha256=wJQpWn_01iWLkr7l7T7RNrQGfRgsgmYi4WQlTmNGvew,618
42
43
  osism/tasks/kubernetes.py,sha256=VzXq_VrYU_CLm4cOruqnE3Kq2ydfO9glZ3p0bp3OYoc,625
43
- osism/tasks/netbox.py,sha256=g0gL5QImiRTHqixRxze7LfNqPth7cXqLzVWQDUJLDjE,5928
44
+ osism/tasks/netbox.py,sha256=QGQGz3s0V8WvPvhEJWwo0H24aLFaZrSl-voN-axzRwY,5846
44
45
  osism/tasks/openstack.py,sha256=g15tCll5vP1pC6ysxRCTZxplsdGmXbxaCH3k1Qdv5Xg,6367
45
- osism/tasks/reconciler.py,sha256=phbSV6urILqq9mHGMYDFwSfx8bLZmldwgEi8sMWs8RA,2040
46
- osism/tasks/conductor/__init__.py,sha256=HW8CXpZOQ6aNgLZ3Ck08YcfQfueoA0ce35Kolh0rWww,1903
47
- osism/tasks/conductor/config.py,sha256=tMI0dtEFSWxfueRZdvocpbEq0sIN_PnXG08CuATkPz4,4489
48
- osism/tasks/conductor/ironic.py,sha256=Gx9LuWNMIMae4a3cVFKsTR4Hm_sr4jLf-JO9QBPSYcg,15402
46
+ osism/tasks/reconciler.py,sha256=PnGWfvfmomzbgddvyCdxul-z5ZLXxWAmrQyRCN874-s,1958
47
+ osism/tasks/conductor/__init__.py,sha256=eAiaM69sVbTTDam7gCLyjF7wBCt7rd__pRFu7VdY-f8,1930
48
+ osism/tasks/conductor/config.py,sha256=n1H9_8DY90p5E4mygzKyJUl8G3WdDuGHFTp-SrmZmgU,4543
49
+ osism/tasks/conductor/ironic.py,sha256=Lfwlcp-rJmQ4CA_1K_FtIRrciaXFNKvC976t1lT2RDs,16090
49
50
  osism/tasks/conductor/netbox.py,sha256=5Nc7wrriDOtSuru1KDLt9QpA54vC7tXDPB2J0JP9GKo,11393
50
51
  osism/tasks/conductor/redfish.py,sha256=hOOS-_l3Qmo_6vLsgjZmJwTxLTf029hhFRVkU0TMLL0,12723
51
- osism/tasks/conductor/utils.py,sha256=ZSbQumQr-uL-B9XOwbsscLIX7czJHu6Mq0t_poRpMsw,7769
52
+ osism/tasks/conductor/utils.py,sha256=-vHsyi0Adlk8qdoZkhM2kUwG7DqwwZZVE0JGK5Z92mI,8127
52
53
  osism/tasks/conductor/sonic/__init__.py,sha256=oxTTl_MGK4iWK9uNDRNlULtGrDGCQHrlJZ04weh_Lh8,777
53
54
  osism/tasks/conductor/sonic/bgp.py,sha256=PC6gGI5bCj2PCXcNGyMV9-EdlJWDsYaodzxigmYSZvw,3088
54
55
  osism/tasks/conductor/sonic/cache.py,sha256=Asv2k3nLJejuq7iB0a_LyK8dEmJzypP9v3OHkNY3GwI,3438
55
- osism/tasks/conductor/sonic/config_generator.py,sha256=Fww6uOC7DplhsqR_jW9PHPB0pAAY1AiTGeNAQ2BUN4k,39259
56
+ osism/tasks/conductor/sonic/config_generator.py,sha256=_B001d6YdhLjAl61WGhlF2xyMXvcyJv0TQ16zuzJjB8,40117
56
57
  osism/tasks/conductor/sonic/connections.py,sha256=NvRjwJv3NF3ry5Xe9qHzk7pQbfDQHYx_j3ATRMUs7gA,14244
57
58
  osism/tasks/conductor/sonic/constants.py,sha256=HjVFwmH-AN3np1qN97ahEAcwz2-4cHa-pA9pXWqWsqs,2219
58
59
  osism/tasks/conductor/sonic/device.py,sha256=ZYJA0bQ8waKWStzWUPxbcwNWa2Z_hMB3pqs8aA_nxXA,2458
59
60
  osism/tasks/conductor/sonic/exporter.py,sha256=25L1vbi84ZQD0xNHNTWk-anTz5QRkGJskCECBkeGQw4,8882
60
- osism/tasks/conductor/sonic/interface.py,sha256=318wOwXYSSMKTPP2WSZIps-JvIkCQ2gYdQs9ZYHXwwg,38957
61
+ osism/tasks/conductor/sonic/interface.py,sha256=QPiggBbk_APWuwwvoU9JWd5bbsdgip9ehFUlcdBKzyI,39329
61
62
  osism/tasks/conductor/sonic/sync.py,sha256=fpgsQVwq6Hb7eeDHhLkAqx5BkaK3Ce_m_WvmWEsJyOo,9182
62
- osism/utils/__init__.py,sha256=gN5VtLJfrvyn6_snuTte7YR-vDygkpbORopIV8qSEsA,6064
63
- osism-0.20250701.0.dist-info/licenses/AUTHORS,sha256=oWotd63qsnNR945QLJP9mEXaXNtCMaesfo8ZNuLjwpU,39
64
- osism-0.20250701.0.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
65
- osism-0.20250701.0.dist-info/METADATA,sha256=3Wd0oo4ezSU0A8zyKit87P9kOS1UANr07qNf_H5Y_QI,2938
66
- osism-0.20250701.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
67
- osism-0.20250701.0.dist-info/entry_points.txt,sha256=xpOV8qyAEuJ6-jrVDnVUUcTCyfBQQ_EOoj5ImcynClM,3476
68
- osism-0.20250701.0.dist-info/pbr.json,sha256=oc9bmpZsjLQNk1EI_gOw4MlbegkQGf47icU8U5FB0iY,47
69
- osism-0.20250701.0.dist-info/top_level.txt,sha256=8L8dsI9hcaGHsdnR4k_LN9EM78EhwrXRFHyAryPXZtY,6
70
- osism-0.20250701.0.dist-info/RECORD,,
63
+ osism/utils/__init__.py,sha256=J2ht-1_9BUV_K6mR6jmk-r_cJKutECFVleEe3-0nU_k,7788
64
+ osism/utils/ssh.py,sha256=nxeEgwjJWvQCybKDp-NelMeWyODCYpaXFCBchAv4-bg,8691
65
+ osism-0.20250804.0.dist-info/licenses/AUTHORS,sha256=oWotd63qsnNR945QLJP9mEXaXNtCMaesfo8ZNuLjwpU,39
66
+ osism-0.20250804.0.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
67
+ osism-0.20250804.0.dist-info/METADATA,sha256=-a3c6DmzquHM97ijxB1bwk5xjuj5uSeYyfuRdsSP0Fw,2937
68
+ osism-0.20250804.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
69
+ osism-0.20250804.0.dist-info/entry_points.txt,sha256=z3hOkBquB5tKZBLGyMV_lgNlzZAqM3LYdC9gClVHFP0,4140
70
+ osism-0.20250804.0.dist-info/pbr.json,sha256=OhImrPgJ50CxjZ7fzWYj8N0JflRxR4HJjRoABlGltrw,47
71
+ osism-0.20250804.0.dist-info/top_level.txt,sha256=8L8dsI9hcaGHsdnR4k_LN9EM78EhwrXRFHyAryPXZtY,6
72
+ osism-0.20250804.0.dist-info/RECORD,,
@@ -3,6 +3,10 @@ osism = osism.main:main
3
3
 
4
4
  [osism.commands]
5
5
  apply = osism.commands.apply:Run
6
+ baremetal deploy = osism.commands.baremetal:BaremetalDeploy
7
+ baremetal list = osism.commands.baremetal:BaremetalList
8
+ baremetal ping = osism.commands.baremetal:BaremetalPing
9
+ baremetal undeploy = osism.commands.baremetal:BaremetalUndeploy
6
10
  compose = osism.commands.compose:Run
7
11
  configuration sync = osism.commands.configuration:Sync
8
12
  console = osism.commands.console:Run
@@ -28,6 +32,7 @@ log file = osism.commands.log:File
28
32
  log opensearch = osism.commands.log:Opensearch
29
33
  manage baremetal deploy = osism.commands.baremetal:BaremetalDeploy
30
34
  manage baremetal list = osism.commands.baremetal:BaremetalList
35
+ manage baremetal ping = osism.commands.baremetal:BaremetalPing
31
36
  manage baremetal undeploy = osism.commands.baremetal:BaremetalUndeploy
32
37
  manage compute disable = osism.commands.compute:ComputeDisable
33
38
  manage compute enable = osism.commands.compute:ComputeEnable
@@ -46,7 +51,6 @@ manage netbox = osism.commands.netbox:Manage
46
51
  manage redfish list = osism.commands.redfish:List
47
52
  manage server list = osism.commands.server:ServerList
48
53
  manage server migrate = osism.commands.server:ServerMigrate
49
- manage sonic = osism.commands.manage:Sonic
50
54
  manage volume list = osism.commands.volume:VolumeList
51
55
  netbox = osism.commands.netbox:Console
52
56
  noset bootstrap = osism.commands.noset:NoBootstrap
@@ -58,6 +62,16 @@ service = osism.commands.service:Run
58
62
  set bootstrap = osism.commands.set:Bootstrap
59
63
  set maintenance = osism.commands.set:Maintenance
60
64
  set vault password = osism.commands.vault:SetPassword
65
+ sonic backup = osism.commands.sonic:Backup
66
+ sonic console = osism.commands.sonic:Console
67
+ sonic list = osism.commands.sonic:List
68
+ sonic load = osism.commands.sonic:Load
69
+ sonic reboot = osism.commands.sonic:Reboot
70
+ sonic reload = osism.commands.sonic:Reload
71
+ sonic reset = osism.commands.sonic:Reset
72
+ sonic show = osism.commands.sonic:Show
73
+ sonic sync = osism.commands.sync:Sonic
74
+ sonic ztp = osism.commands.sonic:Ztp
61
75
  sync configuration = osism.commands.configuration:Sync
62
76
  sync dnsmasq = osism.commands.manage:Dnsmasq
63
77
  sync facts = osism.commands.sync:Facts
@@ -0,0 +1 @@
1
+ {"git_version": "8c96995", "is_release": false}
@@ -1 +0,0 @@
1
- {"git_version": "87129c8", "is_release": false}