osism 0.20250605.0__py3-none-any.whl → 0.20250621.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/commands/baremetal.py +71 -10
- osism/commands/manage.py +25 -1
- osism/commands/netbox.py +22 -5
- osism/commands/reconciler.py +6 -28
- osism/commands/sync.py +48 -1
- osism/commands/validate.py +7 -30
- osism/commands/wait.py +8 -31
- osism/services/listener.py +1 -1
- osism/settings.py +13 -2
- osism/tasks/__init__.py +8 -40
- osism/tasks/conductor/__init__.py +8 -1
- osism/tasks/conductor/ironic.py +90 -66
- osism/tasks/conductor/netbox.py +267 -6
- osism/tasks/conductor/sonic/__init__.py +26 -0
- osism/tasks/conductor/sonic/bgp.py +87 -0
- osism/tasks/conductor/sonic/cache.py +114 -0
- osism/tasks/conductor/sonic/config_generator.py +908 -0
- osism/tasks/conductor/sonic/connections.py +389 -0
- osism/tasks/conductor/sonic/constants.py +79 -0
- osism/tasks/conductor/sonic/device.py +82 -0
- osism/tasks/conductor/sonic/exporter.py +226 -0
- osism/tasks/conductor/sonic/interface.py +789 -0
- osism/tasks/conductor/sonic/sync.py +190 -0
- osism/tasks/conductor.py +2 -0
- osism/tasks/netbox.py +6 -4
- osism/tasks/reconciler.py +4 -5
- osism/utils/__init__.py +51 -4
- {osism-0.20250605.0.dist-info → osism-0.20250621.0.dist-info}/METADATA +4 -4
- {osism-0.20250605.0.dist-info → osism-0.20250621.0.dist-info}/RECORD +35 -25
- {osism-0.20250605.0.dist-info → osism-0.20250621.0.dist-info}/entry_points.txt +5 -0
- osism-0.20250621.0.dist-info/pbr.json +1 -0
- osism-0.20250605.0.dist-info/pbr.json +0 -1
- {osism-0.20250605.0.dist-info → osism-0.20250621.0.dist-info}/WHEEL +0 -0
- {osism-0.20250605.0.dist-info → osism-0.20250621.0.dist-info}/licenses/AUTHORS +0 -0
- {osism-0.20250605.0.dist-info → osism-0.20250621.0.dist-info}/licenses/LICENSE +0 -0
- {osism-0.20250605.0.dist-info → osism-0.20250621.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,190 @@
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
2
|
+
|
3
|
+
"""Main SONiC synchronization function."""
|
4
|
+
|
5
|
+
from loguru import logger
|
6
|
+
|
7
|
+
from osism import utils
|
8
|
+
from osism.tasks.conductor.netbox import get_nb_device_query_list_sonic
|
9
|
+
from .bgp import calculate_minimum_as_for_group
|
10
|
+
from .connections import find_interconnected_devices
|
11
|
+
from .config_generator import generate_sonic_config, clear_all_caches
|
12
|
+
from .constants import DEFAULT_SONIC_ROLES, SUPPORTED_HWSKUS
|
13
|
+
from .exporter import save_config_to_netbox, export_config_to_file
|
14
|
+
from .cache import clear_interface_cache, get_interface_cache_stats
|
15
|
+
|
16
|
+
|
17
|
+
def sync_sonic(device_name=None, task_id=None, show_diff=True):
|
18
|
+
"""Sync SONiC configurations for eligible devices.
|
19
|
+
|
20
|
+
Args:
|
21
|
+
device_name (str, optional): Name of specific device to sync. If None, sync all eligible devices.
|
22
|
+
task_id (str, optional): Task ID for output logging.
|
23
|
+
show_diff (bool, optional): Whether to show diffs when changes are detected. Defaults to True.
|
24
|
+
|
25
|
+
Returns:
|
26
|
+
dict: Dictionary with device names as keys and their SONiC configs as values
|
27
|
+
"""
|
28
|
+
if device_name:
|
29
|
+
logger.info(f"Preparing SONIC configuration for device: {device_name}")
|
30
|
+
else:
|
31
|
+
logger.info("Preparing SONIC configuration files")
|
32
|
+
|
33
|
+
# Clear all caches at start of sync
|
34
|
+
clear_interface_cache()
|
35
|
+
clear_all_caches()
|
36
|
+
logger.debug("Initialized all caches for sync_sonic task")
|
37
|
+
|
38
|
+
# Dictionary to store configurations for all devices
|
39
|
+
device_configs = {}
|
40
|
+
|
41
|
+
logger.debug(f"Supported HWSKUs: {', '.join(SUPPORTED_HWSKUS)}")
|
42
|
+
|
43
|
+
devices = []
|
44
|
+
|
45
|
+
if device_name:
|
46
|
+
# When specific device is requested, fetch it directly
|
47
|
+
try:
|
48
|
+
device = utils.nb.dcim.devices.get(name=device_name)
|
49
|
+
if device:
|
50
|
+
# Check if device role matches allowed roles
|
51
|
+
if device.role and device.role.slug in DEFAULT_SONIC_ROLES:
|
52
|
+
devices.append(device)
|
53
|
+
logger.debug(
|
54
|
+
f"Found device: {device.name} with role: {device.role.slug}"
|
55
|
+
)
|
56
|
+
else:
|
57
|
+
logger.warning(
|
58
|
+
f"Device {device_name} has role '{device.role.slug if device.role else 'None'}' "
|
59
|
+
f"which is not in allowed SONiC roles: {', '.join(DEFAULT_SONIC_ROLES)}"
|
60
|
+
)
|
61
|
+
return device_configs
|
62
|
+
else:
|
63
|
+
logger.error(f"Device {device_name} not found in NetBox")
|
64
|
+
return device_configs
|
65
|
+
except Exception as e:
|
66
|
+
logger.error(f"Error fetching device {device_name}: {e}")
|
67
|
+
return device_configs
|
68
|
+
else:
|
69
|
+
# Get device query list from NETBOX_FILTER_CONDUCTOR_SONIC
|
70
|
+
nb_device_query_list = get_nb_device_query_list_sonic()
|
71
|
+
|
72
|
+
for nb_device_query in nb_device_query_list:
|
73
|
+
# Query devices with the NETBOX_FILTER_CONDUCTOR_SONIC criteria
|
74
|
+
for device in utils.nb.dcim.devices.filter(**nb_device_query):
|
75
|
+
# Check if device role matches allowed roles
|
76
|
+
if device.role and device.role.slug in DEFAULT_SONIC_ROLES:
|
77
|
+
devices.append(device)
|
78
|
+
logger.debug(
|
79
|
+
f"Found device: {device.name} with role: {device.role.slug}"
|
80
|
+
)
|
81
|
+
|
82
|
+
logger.info(f"Found {len(devices)} devices matching criteria")
|
83
|
+
|
84
|
+
# Find interconnected spine/superspine groups for special AS calculation
|
85
|
+
spine_groups = find_interconnected_devices(devices, ["spine", "superspine"])
|
86
|
+
logger.info(f"Found {len(spine_groups)} interconnected spine/superspine groups")
|
87
|
+
|
88
|
+
# Create mapping from device ID to its assigned AS number
|
89
|
+
device_as_mapping = {}
|
90
|
+
|
91
|
+
# Calculate AS numbers for spine/superspine groups
|
92
|
+
for group in spine_groups:
|
93
|
+
min_as = calculate_minimum_as_for_group(group)
|
94
|
+
if min_as:
|
95
|
+
for device in group:
|
96
|
+
device_as_mapping[device.id] = min_as
|
97
|
+
logger.debug(
|
98
|
+
f"Assigned AS {min_as} to {len(group)} devices in spine/superspine group"
|
99
|
+
)
|
100
|
+
|
101
|
+
# Generate SONIC configuration for each device
|
102
|
+
for device in devices:
|
103
|
+
# Get HWSKU from sonic_parameters custom field, default to None
|
104
|
+
hwsku = None
|
105
|
+
if (
|
106
|
+
hasattr(device, "custom_fields")
|
107
|
+
and "sonic_parameters" in device.custom_fields
|
108
|
+
and device.custom_fields["sonic_parameters"]
|
109
|
+
and "hwsku" in device.custom_fields["sonic_parameters"]
|
110
|
+
):
|
111
|
+
hwsku = device.custom_fields["sonic_parameters"]["hwsku"]
|
112
|
+
|
113
|
+
# Skip devices without HWSKU
|
114
|
+
if not hwsku:
|
115
|
+
logger.debug(f"Skipping device {device.name}: no HWSKU configured")
|
116
|
+
continue
|
117
|
+
|
118
|
+
logger.debug(f"Processing device: {device.name} with HWSKU: {hwsku}")
|
119
|
+
|
120
|
+
# Output current device being processed if task_id is available
|
121
|
+
if task_id:
|
122
|
+
utils.push_task_output(task_id, f"Processing device: {device.name}\n")
|
123
|
+
|
124
|
+
# Validate that HWSKU is supported
|
125
|
+
if hwsku not in SUPPORTED_HWSKUS:
|
126
|
+
logger.warning(
|
127
|
+
f"Device {device.name} has unsupported HWSKU: {hwsku}. Supported HWSKUs: {', '.join(SUPPORTED_HWSKUS)}"
|
128
|
+
)
|
129
|
+
continue
|
130
|
+
|
131
|
+
# Generate SONIC configuration based on device HWSKU
|
132
|
+
sonic_config = generate_sonic_config(device, hwsku, device_as_mapping)
|
133
|
+
|
134
|
+
# Store configuration in the dictionary
|
135
|
+
device_configs[device.name] = sonic_config
|
136
|
+
|
137
|
+
# Save the generated configuration to NetBox config context (only if changed)
|
138
|
+
if show_diff:
|
139
|
+
netbox_changed, diff_output = save_config_to_netbox(
|
140
|
+
device, sonic_config, return_diff=True
|
141
|
+
)
|
142
|
+
|
143
|
+
# Output diff to task if available and there are changes
|
144
|
+
if task_id and netbox_changed and diff_output:
|
145
|
+
utils.push_task_output(task_id, f"\n{'='*60}\n")
|
146
|
+
utils.push_task_output(
|
147
|
+
task_id, f"Configuration diff for {device.name}:\n"
|
148
|
+
)
|
149
|
+
utils.push_task_output(task_id, f"{'='*60}\n")
|
150
|
+
utils.push_task_output(task_id, f"{diff_output}\n")
|
151
|
+
utils.push_task_output(task_id, f"{'='*60}\n\n")
|
152
|
+
elif task_id and netbox_changed and not diff_output:
|
153
|
+
# First-time configuration (no diff available)
|
154
|
+
utils.push_task_output(
|
155
|
+
task_id, f"First-time configuration created for {device.name}\n"
|
156
|
+
)
|
157
|
+
else:
|
158
|
+
netbox_changed = save_config_to_netbox(device, sonic_config)
|
159
|
+
|
160
|
+
# Export the generated configuration to local file (only if changed)
|
161
|
+
file_changed = export_config_to_file(device, sonic_config)
|
162
|
+
|
163
|
+
if netbox_changed or file_changed:
|
164
|
+
logger.info(f"Configuration updated for device {device.name}")
|
165
|
+
else:
|
166
|
+
logger.info(f"No configuration changes for device {device.name}")
|
167
|
+
|
168
|
+
logger.info(
|
169
|
+
f"Generated SONiC config for device {device.name} with {len(sonic_config['PORT'])} ports"
|
170
|
+
)
|
171
|
+
|
172
|
+
logger.info(f"Generated SONiC configurations for {len(device_configs)} devices")
|
173
|
+
|
174
|
+
# Log cache statistics and cleanup
|
175
|
+
cache_stats = get_interface_cache_stats()
|
176
|
+
if cache_stats:
|
177
|
+
logger.debug(
|
178
|
+
f"Interface cache stats: {cache_stats['cached_devices']} devices, {cache_stats['total_interfaces']} interfaces"
|
179
|
+
)
|
180
|
+
|
181
|
+
clear_interface_cache()
|
182
|
+
clear_all_caches()
|
183
|
+
logger.debug("Cleared all caches after sync_sonic task completion")
|
184
|
+
|
185
|
+
# Finish task output if task_id is available
|
186
|
+
if task_id:
|
187
|
+
utils.finish_task_output(task_id, rc=0)
|
188
|
+
|
189
|
+
# Return the dictionary with all device configurations
|
190
|
+
return device_configs
|
osism/tasks/conductor.py
CHANGED
osism/tasks/netbox.py
CHANGED
@@ -21,12 +21,14 @@ def run(self, action, arguments):
|
|
21
21
|
pass
|
22
22
|
|
23
23
|
|
24
|
-
# NOTE: While `get_*` tasks only operate on the
|
24
|
+
# NOTE: While `get_*` tasks only operate on the NetBox configured in NETBOX_URL,
|
25
|
+
# `set_*` tasks additionally operate on all NetBox instances listed in
|
26
|
+
# NETBOX_SECONDARIES
|
25
27
|
|
26
28
|
|
27
29
|
@app.task(bind=True, name="osism.tasks.netbox.set_maintenance")
|
28
30
|
def set_maintenance(self, device_name, state=True):
|
29
|
-
"""Set the maintenance state for a device in the
|
31
|
+
"""Set the maintenance state for a device in the NetBox."""
|
30
32
|
|
31
33
|
lock = Redlock(
|
32
34
|
key=f"lock_osism_tasks_netbox_set_maintenance_{device_name}",
|
@@ -55,7 +57,7 @@ def set_maintenance(self, device_name, state=True):
|
|
55
57
|
|
56
58
|
@app.task(bind=True, name="osism.tasks.netbox.set_provision_state")
|
57
59
|
def set_provision_state(self, device_name, state):
|
58
|
-
"""Set the provision state for a device in the
|
60
|
+
"""Set the provision state for a device in the NetBox."""
|
59
61
|
|
60
62
|
lock = Redlock(
|
61
63
|
key=f"lock_osism_tasks_netbox_set_provision_state_{device_name}",
|
@@ -85,7 +87,7 @@ def set_provision_state(self, device_name, state):
|
|
85
87
|
|
86
88
|
@app.task(bind=True, name="osism.tasks.netbox.set_power_state")
|
87
89
|
def set_power_state(self, device_name, state):
|
88
|
-
"""Set the provision state for a device in the
|
90
|
+
"""Set the provision state for a device in the NetBox."""
|
89
91
|
|
90
92
|
lock = Redlock(
|
91
93
|
key=f"lock_osism_tasks_netbox_set_provision_state_{device_name}",
|
osism/tasks/reconciler.py
CHANGED
@@ -40,15 +40,14 @@ def run(self, publish=True):
|
|
40
40
|
"/run.sh", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
41
41
|
)
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
utils.
|
43
|
+
if publish:
|
44
|
+
for line in io.TextIOWrapper(p.stdout, encoding="utf-8"):
|
45
|
+
utils.push_task_output(self.request.id, line)
|
46
46
|
|
47
47
|
rc = p.wait(timeout=60)
|
48
48
|
|
49
49
|
if publish:
|
50
|
-
utils.
|
51
|
-
utils.redis.xadd(self.request.id, {"type": "action", "content": "quit"})
|
50
|
+
utils.finish_task_output(self.request.id, rc=rc)
|
52
51
|
|
53
52
|
lock.release()
|
54
53
|
|
osism/utils/__init__.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# SPDX-License-Identifier: Apache-2.0
|
2
2
|
|
3
|
+
import time
|
4
|
+
import os
|
3
5
|
from cryptography.fernet import Fernet
|
4
6
|
import keystoneauth1
|
5
7
|
from loguru import logger
|
@@ -48,12 +50,12 @@ try:
|
|
48
50
|
secondary_nb_list = []
|
49
51
|
if type(secondary_nb_settings_list) is not list:
|
50
52
|
raise TypeError(
|
51
|
-
f"Setting NETBOX_SECONDARIES needs to be an array of mappings containing supported
|
53
|
+
f"Setting NETBOX_SECONDARIES needs to be an array of mappings containing supported NetBox API configuration: {supported_secondary_nb_keys}"
|
52
54
|
)
|
53
55
|
for secondary_nb_settings in secondary_nb_settings_list:
|
54
56
|
if type(secondary_nb_settings) is not dict:
|
55
57
|
raise TypeError(
|
56
|
-
f"Elements in setting NETBOX_SECONDARIES need to be mappings containing supported
|
58
|
+
f"Elements in setting NETBOX_SECONDARIES need to be mappings containing supported NetBox API configuration: {supported_secondary_nb_keys}"
|
57
59
|
)
|
58
60
|
for key in list(secondary_nb_settings.keys()):
|
59
61
|
if key not in supported_secondary_nb_keys:
|
@@ -65,14 +67,14 @@ try:
|
|
65
67
|
or not secondary_nb_settings["NETBOX_URL"]
|
66
68
|
):
|
67
69
|
raise ValueError(
|
68
|
-
"All NETBOX_URL values in the elements of setting NETBOX_SECONDARIES need to be valid
|
70
|
+
"All NETBOX_URL values in the elements of setting NETBOX_SECONDARIES need to be valid NetBox URLs"
|
69
71
|
)
|
70
72
|
if (
|
71
73
|
"NETBOX_TOKEN" not in secondary_nb_settings
|
72
74
|
or not secondary_nb_settings["NETBOX_TOKEN"]
|
73
75
|
):
|
74
76
|
raise ValueError(
|
75
|
-
"All NETBOX_TOKEN values in the elements of setting NETBOX_SECONDARIES need to be valid
|
77
|
+
"All NETBOX_TOKEN values in the elements of setting NETBOX_SECONDARIES need to be valid NetBox tokens"
|
76
78
|
)
|
77
79
|
|
78
80
|
secondary_nb_list.append(
|
@@ -134,3 +136,48 @@ def first(iterable, condition=lambda x: True):
|
|
134
136
|
"""
|
135
137
|
|
136
138
|
return next(x for x in iterable if condition(x))
|
139
|
+
|
140
|
+
|
141
|
+
def fetch_task_output(
|
142
|
+
task_id, timeout=os.environ.get("OSISM_TASK_TIMEOUT", 300), enable_play_recap=False
|
143
|
+
):
|
144
|
+
rc = 0
|
145
|
+
stoptime = time.time() + timeout
|
146
|
+
last_id = 0
|
147
|
+
while time.time() < stoptime:
|
148
|
+
data = redis.xread({str(task_id): last_id}, count=1, block=(timeout * 1000))
|
149
|
+
if data:
|
150
|
+
stoptime = time.time() + timeout
|
151
|
+
messages = data[0]
|
152
|
+
for message_id, message in messages[1]:
|
153
|
+
last_id = message_id.decode()
|
154
|
+
message_type = message[b"type"].decode()
|
155
|
+
message_content = message[b"content"].decode()
|
156
|
+
|
157
|
+
logger.debug(f"Processing message {last_id} of type {message_type}")
|
158
|
+
redis.xdel(str(task_id), last_id)
|
159
|
+
|
160
|
+
if message_type == "stdout":
|
161
|
+
print(message_content, end="")
|
162
|
+
if enable_play_recap and "PLAY RECAP" in message_content:
|
163
|
+
logger.info(
|
164
|
+
"Play has been completed. There may now be a delay until "
|
165
|
+
"all logs have been written."
|
166
|
+
)
|
167
|
+
logger.info("Please wait and do not abort execution.")
|
168
|
+
elif message_type == "rc":
|
169
|
+
rc = int(message_content)
|
170
|
+
elif message_type == "action" and message_content == "quit":
|
171
|
+
redis.close()
|
172
|
+
return rc
|
173
|
+
raise TimeoutError
|
174
|
+
|
175
|
+
|
176
|
+
def push_task_output(task_id, line):
|
177
|
+
redis.xadd(task_id, {"type": "stdout", "content": line})
|
178
|
+
|
179
|
+
|
180
|
+
def finish_task_output(task_id, rc=None):
|
181
|
+
if rc:
|
182
|
+
redis.xadd(task_id, {"type": "rc", "content": rc})
|
183
|
+
redis.xadd(task_id, {"type": "action", "content": "quit"})
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: osism
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.20250621.0
|
4
4
|
Summary: OSISM manager interface
|
5
5
|
Home-page: https://github.com/osism/python-osism
|
6
6
|
Author: OSISM GmbH
|
@@ -32,13 +32,13 @@ 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.
|
35
|
+
Requires-Dist: fastapi==0.115.13
|
36
36
|
Requires-Dist: flower==2.0.1
|
37
37
|
Requires-Dist: hiredis==3.2.1
|
38
38
|
Requires-Dist: jc==1.25.5
|
39
|
-
Requires-Dist: keystoneauth1==5.11.
|
39
|
+
Requires-Dist: keystoneauth1==5.11.1
|
40
40
|
Requires-Dist: kombu==5.5.4
|
41
|
-
Requires-Dist: kubernetes==
|
41
|
+
Requires-Dist: kubernetes==33.1.0
|
42
42
|
Requires-Dist: loguru==0.7.3
|
43
43
|
Requires-Dist: nbcli==0.10.0.dev2
|
44
44
|
Requires-Dist: netmiko==4.5.0
|
@@ -2,11 +2,11 @@ osism/__init__.py,sha256=1UiNTBus0V0f2AbZQzAtVtu6zkfCCrw0OTq--NwFAqY,341
|
|
2
2
|
osism/__main__.py,sha256=ILe4gu61xEISiBsxanqTQIdSkV-YhpZXTRlguCYyssk,141
|
3
3
|
osism/api.py,sha256=t3HebSzk6fyY7bLJD9P95oEL1qWYXzpX6Yk1o_nVkMo,4356
|
4
4
|
osism/main.py,sha256=Dt2-9sLXcS-Ny4DAz7hrha-KRc7zd7BFUTRdfs_X8z4,893
|
5
|
-
osism/settings.py,sha256=
|
5
|
+
osism/settings.py,sha256=bebPBT6Hd1-KhJfwZdFR-s8eMwV4B1IFr-WrQBkOrWw,1786
|
6
6
|
osism/actions/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
|
7
7
|
osism/commands/__init__.py,sha256=Ag4wX_DCgXRdoLn6t069jqb3DdRylsX2nyYkiyCx4uk,456
|
8
8
|
osism/commands/apply.py,sha256=q645f4qxmOAaUjVD7npzM2aNuOqfptVAkCLfE6x5IV8,16833
|
9
|
-
osism/commands/baremetal.py,sha256=
|
9
|
+
osism/commands/baremetal.py,sha256=w1LyZDms-DtULsF_76JsauOYHc2tcvoMRP6F9dYby9E,10688
|
10
10
|
osism/commands/compose.py,sha256=iqzG7mS9E1VWaLNN6yQowjOqiHn3BMdj-yfXb3Dc4Ok,1200
|
11
11
|
osism/commands/compute.py,sha256=cgqXWJa5wAvn-7e3FWCgX6hie_aK0yrKRkcNzjLXwDY,25799
|
12
12
|
osism/commands/configuration.py,sha256=sPe8b0dVKFRbr30xoeVdAnHbGwCwgUh0xa_Vzv5pSQQ,954
|
@@ -14,20 +14,20 @@ osism/commands/console.py,sha256=8BPz1hio5Wi6kONVAWFuSqkDRrMcLEYeFIY8dbtN6e4,321
|
|
14
14
|
osism/commands/container.py,sha256=Fku2GaCM3Idq_FxExUtNqjrEM0XYjpVvXmueSVO8S_c,1601
|
15
15
|
osism/commands/get.py,sha256=ryytjtXWmlMV0NucP5tGkMZu0nIlC4xVtjRk4iMZ06c,8967
|
16
16
|
osism/commands/log.py,sha256=2IpYuosC7FZwwLvM8HmKSU1NRNIelVVYzqjjVMCrOJk,4072
|
17
|
-
osism/commands/manage.py,sha256=
|
18
|
-
osism/commands/netbox.py,sha256=
|
17
|
+
osism/commands/manage.py,sha256=FaO9dbYjNHYanS98-zC498bx26oU8E3loxCczH9mfKI,12751
|
18
|
+
osism/commands/netbox.py,sha256=e65P0kWrjTLw2T9HZthxjDTIRa-KAHgSSJAlvVef7n4,7345
|
19
19
|
osism/commands/noset.py,sha256=7zDFuFMyNpo7DUOKcNiYV8nodtdMOYFp5LDPcuJhlZ8,1481
|
20
|
-
osism/commands/reconciler.py,sha256=
|
20
|
+
osism/commands/reconciler.py,sha256=jy07Qbl219e-WCtWbtV9zh49qHHCjDMm6oVTJM61k1A,1958
|
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
24
|
osism/commands/status.py,sha256=X-Rcj-XuNPDBoxsGkf96NswwpmTognxz1V6E2NX2ZgY,1997
|
25
|
-
osism/commands/sync.py,sha256=
|
25
|
+
osism/commands/sync.py,sha256=jOg-g8NmVOkXBI6rOuiOx2WgUJc1PplLAAAwc0VuIfw,1919
|
26
26
|
osism/commands/task.py,sha256=mwJJ7a71Lw3o_FX7j3rR0-NbPdPwMDOjbOAiiXE4uGc,543
|
27
|
-
osism/commands/validate.py,sha256=
|
27
|
+
osism/commands/validate.py,sha256=E1n1kEo6h8J5c7Ns5OHpr0R7i4IU6uj08LE_gt3kBCg,3262
|
28
28
|
osism/commands/vault.py,sha256=llaqNN8UH8t8cCu2KmdaURvprA4zeG6izCen_W7ulPs,2029
|
29
29
|
osism/commands/volume.py,sha256=l6oAk__dFM8KKdLTWOvuSiI7tLh9wAPZp8hwmYF-NX0,6595
|
30
|
-
osism/commands/wait.py,sha256=
|
30
|
+
osism/commands/wait.py,sha256=2Ncx63M0AFq4fq40VZVClf1LS-WHetD8iC_mG2dY_Cw,5275
|
31
31
|
osism/commands/worker.py,sha256=iraCOEhCp7WgfjfZ0-12XQYQPUjpi9rSJK5Z9JfNJk4,1651
|
32
32
|
osism/core/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
|
33
33
|
osism/core/enums.py,sha256=gItIjOK6xWuOZSkMxpMdYLRyt4ezyhzkqA7BGiah2o0,10030
|
@@ -35,27 +35,37 @@ osism/core/playbooks.py,sha256=M3T3ajV-8Lt-orsRO3jAoukhaoYFr4EZ2dzYXQjt1kg,728
|
|
35
35
|
osism/data/__init__.py,sha256=izXdh0J3vPLQI7kBhJI7ibJQzPqU_nlONP0L4Cf_k6A,1504
|
36
36
|
osism/plugins/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
|
37
37
|
osism/services/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
|
38
|
-
osism/services/listener.py,sha256=
|
39
|
-
osism/tasks/__init__.py,sha256=
|
38
|
+
osism/services/listener.py,sha256=Vf8LOZkHzlspm40BZ1az3o1O_ar34_i6C83p-D8KzzM,9783
|
39
|
+
osism/tasks/__init__.py,sha256=kocG0q2bARhkkSjMBH2xWdFUIJodesdh5qVsV_DqZmE,7148
|
40
40
|
osism/tasks/ansible.py,sha256=_2zrHwynwwEv9nDnX-LbNCzcwy9dTUGo_yyutt34HyQ,1346
|
41
41
|
osism/tasks/ceph.py,sha256=eIQkah3Kj4INtOkF9kTjHbXJ3_J2lg48EWJKfHc-UYw,615
|
42
|
-
osism/tasks/conductor.py,sha256=
|
42
|
+
osism/tasks/conductor.py,sha256=WBLsoPtr0iGUzRGERs0Xt7CMYrnHQVEwNV9qXBssI3s,274
|
43
43
|
osism/tasks/kolla.py,sha256=wJQpWn_01iWLkr7l7T7RNrQGfRgsgmYi4WQlTmNGvew,618
|
44
44
|
osism/tasks/kubernetes.py,sha256=VzXq_VrYU_CLm4cOruqnE3Kq2ydfO9glZ3p0bp3OYoc,625
|
45
|
-
osism/tasks/netbox.py,sha256=
|
45
|
+
osism/tasks/netbox.py,sha256=g0gL5QImiRTHqixRxze7LfNqPth7cXqLzVWQDUJLDjE,5928
|
46
46
|
osism/tasks/openstack.py,sha256=g15tCll5vP1pC6ysxRCTZxplsdGmXbxaCH3k1Qdv5Xg,6367
|
47
|
-
osism/tasks/reconciler.py,sha256=
|
48
|
-
osism/tasks/conductor/__init__.py,sha256=
|
47
|
+
osism/tasks/reconciler.py,sha256=6iC0EYxeGvitzU2NsRqQzUEDZWW6Il3jgq_IRTN0sZg,1855
|
48
|
+
osism/tasks/conductor/__init__.py,sha256=eBkisjRj0YRT0AArvuvpIHGNEqEijsNvR_55BuVX62I,1600
|
49
49
|
osism/tasks/conductor/config.py,sha256=tvfuYNgvw0F_ZbvrjqnyHfrj3vF6z0zhsRtGNu-Lgvo,3410
|
50
|
-
osism/tasks/conductor/ironic.py,sha256=
|
51
|
-
osism/tasks/conductor/netbox.py,sha256=
|
50
|
+
osism/tasks/conductor/ironic.py,sha256=tIhKH5EWvqzjVtZr32du8_jiVDP_9mFgTkxBjmtEm6g,16487
|
51
|
+
osism/tasks/conductor/netbox.py,sha256=5Nc7wrriDOtSuru1KDLt9QpA54vC7tXDPB2J0JP9GKo,11393
|
52
52
|
osism/tasks/conductor/utils.py,sha256=-a0-pRuhV4Fjj0SgdgBqtRJtAdGdqck5pzfi6NYBApU,2338
|
53
|
-
osism/
|
54
|
-
osism
|
55
|
-
osism
|
56
|
-
osism
|
57
|
-
osism
|
58
|
-
osism
|
59
|
-
osism
|
60
|
-
osism
|
61
|
-
osism
|
53
|
+
osism/tasks/conductor/sonic/__init__.py,sha256=oxTTl_MGK4iWK9uNDRNlULtGrDGCQHrlJZ04weh_Lh8,777
|
54
|
+
osism/tasks/conductor/sonic/bgp.py,sha256=PC6gGI5bCj2PCXcNGyMV9-EdlJWDsYaodzxigmYSZvw,3088
|
55
|
+
osism/tasks/conductor/sonic/cache.py,sha256=Asv2k3nLJejuq7iB0a_LyK8dEmJzypP9v3OHkNY3GwI,3438
|
56
|
+
osism/tasks/conductor/sonic/config_generator.py,sha256=Z2i6SvKp27EI-dK9fkSDo51ghbIIqTgM7qK0-xJtVwU,35098
|
57
|
+
osism/tasks/conductor/sonic/connections.py,sha256=NvRjwJv3NF3ry5Xe9qHzk7pQbfDQHYx_j3ATRMUs7gA,14244
|
58
|
+
osism/tasks/conductor/sonic/constants.py,sha256=nfsiKV1I5iiXPAUzkZgnFPWuSB_oy8xg3gNEZjn1Hb4,2194
|
59
|
+
osism/tasks/conductor/sonic/device.py,sha256=ZYJA0bQ8waKWStzWUPxbcwNWa2Z_hMB3pqs8aA_nxXA,2458
|
60
|
+
osism/tasks/conductor/sonic/exporter.py,sha256=25L1vbi84ZQD0xNHNTWk-anTz5QRkGJskCECBkeGQw4,8882
|
61
|
+
osism/tasks/conductor/sonic/interface.py,sha256=MM-HrYlVdh_5fYSKto_38DC4RcfzoqBGEYFxk-Tz760,32233
|
62
|
+
osism/tasks/conductor/sonic/sync.py,sha256=Jh2xbBv_yyrEJZZZkZRIk7vH0WV-IS4CA-4qQp56I2U,7823
|
63
|
+
osism/utils/__init__.py,sha256=gN5VtLJfrvyn6_snuTte7YR-vDygkpbORopIV8qSEsA,6064
|
64
|
+
osism-0.20250621.0.dist-info/licenses/AUTHORS,sha256=oWotd63qsnNR945QLJP9mEXaXNtCMaesfo8ZNuLjwpU,39
|
65
|
+
osism-0.20250621.0.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
|
66
|
+
osism-0.20250621.0.dist-info/METADATA,sha256=0nTzEqeDkHWwUyPJftfn6_Az0MP26rQjhMQNPffXkdM,2903
|
67
|
+
osism-0.20250621.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
68
|
+
osism-0.20250621.0.dist-info/entry_points.txt,sha256=X1KbMeQim23k_lGGDFz8ldQIrdCrq8mKnFWgYrrEZI0,3469
|
69
|
+
osism-0.20250621.0.dist-info/pbr.json,sha256=nvF1nN4eUUNsct1PT2Fq9FvN3QNGbPvpeeWGR0BjJjU,47
|
70
|
+
osism-0.20250621.0.dist-info/top_level.txt,sha256=8L8dsI9hcaGHsdnR4k_LN9EM78EhwrXRFHyAryPXZtY,6
|
71
|
+
osism-0.20250621.0.dist-info/RECORD,,
|
@@ -37,13 +37,16 @@ manage compute migrate = osism.commands.compute:ComputeMigrate
|
|
37
37
|
manage compute migration list = osism.commands.compute:ComputeMigrationList
|
38
38
|
manage compute start = osism.commands.compute:ComputeStart
|
39
39
|
manage compute stop = osism.commands.compute:ComputeStop
|
40
|
+
manage dnsmasq = osism.commands.manage:Dnsmasq
|
40
41
|
manage flavors = osism.commands.manage:Flavors
|
41
42
|
manage image clusterapi = osism.commands.manage:ImageClusterapi
|
42
43
|
manage image octavia = osism.commands.manage:ImageOctavia
|
43
44
|
manage images = osism.commands.manage:Images
|
45
|
+
manage ironic = osism.commands.netbox:Ironic
|
44
46
|
manage netbox = osism.commands.netbox:Manage
|
45
47
|
manage server list = osism.commands.server:ServerList
|
46
48
|
manage server migrate = osism.commands.server:ServerMigrate
|
49
|
+
manage sonic = osism.commands.sync:Sonic
|
47
50
|
manage volume list = osism.commands.volume:VolumeList
|
48
51
|
netbox = osism.commands.netbox:Console
|
49
52
|
noset bootstrap = osism.commands.noset:NoBootstrap
|
@@ -56,10 +59,12 @@ set bootstrap = osism.commands.set:Bootstrap
|
|
56
59
|
set maintenance = osism.commands.set:Maintenance
|
57
60
|
set vault password = osism.commands.vault:SetPassword
|
58
61
|
sync configuration = osism.commands.configuration:Sync
|
62
|
+
sync dnsmasq = osism.commands.manage:Dnsmasq
|
59
63
|
sync facts = osism.commands.sync:Facts
|
60
64
|
sync inventory = osism.commands.reconciler:Sync
|
61
65
|
sync ironic = osism.commands.netbox:Ironic
|
62
66
|
sync netbox = osism.commands.netbox:Sync
|
67
|
+
sync sonic = osism.commands.sync:Sonic
|
63
68
|
task list = osism.commands.get:Tasks
|
64
69
|
task revoke = osism.commands.task:Revoke
|
65
70
|
validate = osism.commands.validate:Run
|
@@ -0,0 +1 @@
|
|
1
|
+
{"git_version": "ed0a34c", "is_release": false}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"git_version": "f816350", "is_release": false}
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|