osism 0.20241219.2__py3-none-any.whl → 0.20250312.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/api.py +18 -0
- osism/services/listener.py +261 -131
- osism/settings.py +2 -0
- osism-0.20250312.0.dist-info/AUTHORS +1 -0
- {osism-0.20241219.2.dist-info → osism-0.20250312.0.dist-info}/METADATA +26 -18
- {osism-0.20241219.2.dist-info → osism-0.20250312.0.dist-info}/RECORD +11 -11
- {osism-0.20241219.2.dist-info → osism-0.20250312.0.dist-info}/WHEEL +1 -1
- osism-0.20250312.0.dist-info/pbr.json +1 -0
- osism-0.20241219.2.dist-info/AUTHORS +0 -1
- osism-0.20241219.2.dist-info/pbr.json +0 -1
- {osism-0.20241219.2.dist-info → osism-0.20250312.0.dist-info}/LICENSE +0 -0
- {osism-0.20241219.2.dist-info → osism-0.20250312.0.dist-info}/entry_points.txt +0 -0
- {osism-0.20241219.2.dist-info → osism-0.20250312.0.dist-info}/top_level.txt +0 -0
osism/api.py
CHANGED
@@ -12,6 +12,16 @@ from starlette.middleware.cors import CORSMiddleware
|
|
12
12
|
|
13
13
|
from osism.tasks import reconciler
|
14
14
|
from osism import settings
|
15
|
+
from osism.services.listener import BaremetalEvents
|
16
|
+
|
17
|
+
|
18
|
+
class NotificationBaremetal(BaseModel):
|
19
|
+
priority: str
|
20
|
+
event_type: str
|
21
|
+
timestamp: str
|
22
|
+
publisher_id: str
|
23
|
+
message_id: UUID
|
24
|
+
payload: dict
|
15
25
|
|
16
26
|
|
17
27
|
class WebhookNetboxResponse(BaseModel):
|
@@ -66,6 +76,7 @@ dictConfig(LogConfig().dict())
|
|
66
76
|
logger = logging.getLogger("api")
|
67
77
|
|
68
78
|
nb = None
|
79
|
+
baremetal_events = BaremetalEvents()
|
69
80
|
|
70
81
|
|
71
82
|
@app.on_event("startup")
|
@@ -99,6 +110,13 @@ async def write_sink_events(request: Request):
|
|
99
110
|
data = await request.json()
|
100
111
|
|
101
112
|
|
113
|
+
@app.post("/notifications/baremetal", status_code=204)
|
114
|
+
async def notifications_baremetal(notification: NotificationBaremetal) -> None:
|
115
|
+
|
116
|
+
handler = baremetal_events.get_handler(notification.event_type)
|
117
|
+
handler(notification.payload)
|
118
|
+
|
119
|
+
|
102
120
|
@app.post("/webhook/netbox", response_model=WebhookNetboxResponse, status_code=200)
|
103
121
|
async def webhook(
|
104
122
|
webhook_input: WebhookNetboxData,
|
osism/services/listener.py
CHANGED
@@ -2,14 +2,18 @@
|
|
2
2
|
|
3
3
|
import os
|
4
4
|
import time
|
5
|
+
from collections.abc import Callable
|
6
|
+
from typing import Any
|
5
7
|
|
6
8
|
from kombu import Connection, Exchange, Queue
|
7
9
|
from kombu.mixins import ConsumerMixin
|
8
10
|
from loguru import logger
|
9
11
|
import json
|
12
|
+
import requests
|
10
13
|
|
11
14
|
from osism import utils
|
12
15
|
from osism.tasks import netbox, openstack
|
16
|
+
from osism import settings
|
13
17
|
|
14
18
|
EXCHANGE_NAME = "ironic"
|
15
19
|
ROUTING_KEY = "ironic_versioned_notifications.info"
|
@@ -17,168 +21,294 @@ QUEUE_NAME = "osism-listener-ironic"
|
|
17
21
|
BROKER_URI = os.getenv("BROKER_URI")
|
18
22
|
|
19
23
|
|
20
|
-
class
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
+
class BaremetalEvents:
|
25
|
+
# References:
|
26
|
+
#
|
27
|
+
# * https://docs.openstack.org/ironic/latest/admin/notifications.html#available-notifications
|
28
|
+
# * https://docs.openstack.org/ironic/latest/user/states.html
|
29
|
+
# * https://docs.openstack.org/ironic/latest/_images/states.svg
|
30
|
+
|
31
|
+
def __init__(self) -> None:
|
32
|
+
self._handler: dict[
|
33
|
+
str, dict[str, dict[str, dict[str, Callable[[dict[Any, Any]], None]]]]
|
34
|
+
] = {
|
35
|
+
"baremetal": {
|
36
|
+
"node": {
|
37
|
+
"power_set": {"end": self.node_power_set_end},
|
38
|
+
"power_state_corrected": {
|
39
|
+
"success": self.node_power_state_corrected_success
|
40
|
+
},
|
41
|
+
"maintenance_set": {"end": self.node_maintenance_set_end},
|
42
|
+
"provision_set": {
|
43
|
+
"start": self.node_provision_set_start,
|
44
|
+
"end": self.node_provision_set_end,
|
45
|
+
"success": self.node_provision_set_success,
|
46
|
+
},
|
47
|
+
"delete": {"end": self.node_delete_end},
|
48
|
+
"create": {"end": self.node_create_end},
|
49
|
+
},
|
50
|
+
"port": {
|
51
|
+
"create": {"end": self.port_create_end},
|
52
|
+
"update": {"end": self.port_update_end},
|
53
|
+
},
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
def get_object_data(self, payload: dict[Any, Any]) -> Any:
|
58
|
+
return payload["ironic_object.data"]
|
59
|
+
|
60
|
+
def get_handler(self, event_type: str) -> Callable[[dict[Any, Any]], None]:
|
61
|
+
event_type_keys = event_type.split(".")
|
62
|
+
try:
|
63
|
+
handler = self._handler[event_type_keys[0]][event_type_keys[1]][
|
64
|
+
event_type_keys[2]
|
65
|
+
][event_type_keys[3]]
|
66
|
+
except KeyError:
|
24
67
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
68
|
+
def default_handler(payload: dict[Any, Any]) -> None:
|
69
|
+
object_data = self.get_object_data(payload)
|
70
|
+
name = object_data["name"]
|
71
|
+
logger.info(event_type + f" ## {name}")
|
72
|
+
|
73
|
+
handler = default_handler
|
74
|
+
return handler
|
75
|
+
|
76
|
+
def node_power_set_end(self, payload: dict[Any, Any]) -> None:
|
77
|
+
object_data = self.get_object_data(payload)
|
78
|
+
name = object_data["name"]
|
79
|
+
logger.info(
|
80
|
+
f"baremetal.node.power_set.end ## {name} ## {object_data['power_state']}"
|
34
81
|
)
|
35
|
-
|
82
|
+
netbox.set_state.delay(name, object_data["power_state"], "power")
|
36
83
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
84
|
+
def node_power_state_corrected_success(self, payload: dict[Any, Any]) -> None:
|
85
|
+
object_data = self.get_object_data(payload)
|
86
|
+
name = object_data["name"]
|
87
|
+
logger.info(
|
88
|
+
f"baremetal.node.power_state_corrected.success ## {name} ## {object_data['power_state']}"
|
89
|
+
)
|
90
|
+
netbox.set_state.delay(name, object_data["power_state"], "power")
|
40
91
|
|
41
|
-
|
42
|
-
|
43
|
-
|
92
|
+
def node_maintenance_set_end(self, payload: dict[Any, Any]) -> None:
|
93
|
+
object_data = self.get_object_data(payload)
|
94
|
+
name = object_data["name"]
|
95
|
+
logger.info(
|
96
|
+
f"baremetal.node.maintenance_set.end ## {name} ## {object_data['maintenance']}"
|
97
|
+
)
|
98
|
+
netbox.set_maintenance.delay(name, object_data["maintenance"])
|
44
99
|
|
100
|
+
def node_provision_set_start(self, payload: dict[Any, Any]) -> None:
|
101
|
+
object_data = self.get_object_data(payload)
|
45
102
|
name = object_data["name"]
|
103
|
+
logger.info(
|
104
|
+
f"baremetal.node.provision_set.start ## {name} ## {object_data['provision_state']}"
|
105
|
+
)
|
46
106
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
# * https://docs.openstack.org/ironic/latest/user/states.html
|
51
|
-
# * https://docs.openstack.org/ironic/latest/_images/states.svg
|
107
|
+
if object_data["event"] == "inspect":
|
108
|
+
# system should be in state a
|
109
|
+
netbox.connect.delay(name, "a")
|
52
110
|
|
53
|
-
if
|
54
|
-
|
55
|
-
|
56
|
-
)
|
57
|
-
netbox.set_state.delay(name, object_data["power_state"], "power")
|
111
|
+
if object_data["provision_state"] == "cleaning":
|
112
|
+
# system should be in state b
|
113
|
+
netbox.connect.delay(name, "b")
|
58
114
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
)
|
63
|
-
netbox.set_state.delay(name, object_data["power_state"], "power")
|
115
|
+
if object_data["provision_state"] == "available":
|
116
|
+
# system should be in state c
|
117
|
+
netbox.connect.delay(name, "c")
|
64
118
|
|
65
|
-
|
66
|
-
|
67
|
-
f"baremetal.node.maintenance_set.end ## {name} ## {object_data['maintenance']}"
|
68
|
-
)
|
69
|
-
netbox.set_maintenance.delay(name, object_data["maintenance"])
|
119
|
+
if object_data["target_provision_state"] == "active":
|
120
|
+
pass
|
70
121
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
122
|
+
def node_provision_set_success(self, payload: dict[Any, Any]) -> None:
|
123
|
+
# A provision status was successfully set, update it in the netbox
|
124
|
+
object_data = self.get_object_data(payload)
|
125
|
+
name = object_data["name"]
|
126
|
+
logger.info(
|
127
|
+
f"baremetal.node.provision_set.success ## {name} ## {object_data['provision_state']}"
|
128
|
+
)
|
129
|
+
netbox.set_state.delay(name, object_data["provision_state"], "provision")
|
75
130
|
|
76
|
-
|
77
|
-
|
78
|
-
|
131
|
+
if object_data["provision_state"] == "manageable":
|
132
|
+
# system should be in state c
|
133
|
+
netbox.connect.delay(name, "c")
|
79
134
|
|
80
|
-
|
81
|
-
|
82
|
-
|
135
|
+
def node_provision_set_end(self, payload: dict[Any, Any]) -> None:
|
136
|
+
object_data = self.get_object_data(payload)
|
137
|
+
name = object_data["name"]
|
138
|
+
logger.info(
|
139
|
+
f"baremetal.node.provision_set.end ## {name} ## {object_data['provision_state']}"
|
140
|
+
)
|
141
|
+
netbox.set_state.delay(name, object_data["provision_state"], "provision")
|
142
|
+
|
143
|
+
if (
|
144
|
+
object_data["previous_provision_state"] == "inspect wait"
|
145
|
+
and object_data["event"] == "done"
|
146
|
+
):
|
147
|
+
netbox.set_state.delay(name, "introspected", "introspection")
|
148
|
+
openstack.baremetal_set_node_provision_state.delay(name, "provide")
|
149
|
+
|
150
|
+
elif object_data["previous_provision_state"] == "wait call-back":
|
151
|
+
pass
|
152
|
+
|
153
|
+
elif (
|
154
|
+
object_data["previous_provision_state"] == "cleaning"
|
155
|
+
and object_data["provision_state"] == "available"
|
156
|
+
): # noqa
|
157
|
+
# system should be in state c
|
158
|
+
netbox.connect.delay(name, "c")
|
159
|
+
|
160
|
+
def port_create_end(self, payload: dict[Any, Any]) -> None:
|
161
|
+
object_data = self.get_object_data(payload)
|
162
|
+
name = object_data["name"]
|
163
|
+
logger.info(f"baremetal.port.create.end ## {object_data['uuid']}")
|
83
164
|
|
84
|
-
|
85
|
-
|
86
|
-
|
165
|
+
mac_address = object_data["address"]
|
166
|
+
interface_a = utils.nb.dcim.interfaces.get(mac_address=mac_address)
|
167
|
+
device_a = interface_a.device
|
87
168
|
|
88
|
-
|
89
|
-
|
169
|
+
task = openstack.baremetal_get_network_interface_name.delay(
|
170
|
+
device_a.name, mac_address
|
171
|
+
)
|
172
|
+
task.wait(timeout=None, interval=0.5)
|
173
|
+
network_interface_name = task.get()
|
90
174
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
f"baremetal.node.provision_set.success ## {name} ## {object_data['provision_state']}"
|
95
|
-
)
|
96
|
-
netbox.set_state.delay(name, object_data["provision_state"], "provision")
|
175
|
+
netbox.update_network_interface_name.delay(
|
176
|
+
object_data["address"], network_interface_name
|
177
|
+
)
|
97
178
|
|
98
|
-
|
99
|
-
|
100
|
-
|
179
|
+
def port_update_end(self, payload: dict[Any, Any]) -> None:
|
180
|
+
object_data = self.get_object_data(payload)
|
181
|
+
name = object_data["name"]
|
182
|
+
logger.info(f"baremetal.port.update.end ## {object_data['uuid']}")
|
101
183
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
)
|
106
|
-
netbox.set_state.delay(name, object_data["provision_state"], "provision")
|
107
|
-
|
108
|
-
if (
|
109
|
-
object_data["previous_provision_state"] == "inspect wait"
|
110
|
-
and object_data["event"] == "done"
|
111
|
-
):
|
112
|
-
netbox.set_state.delay(name, "introspected", "introspection")
|
113
|
-
openstack.baremetal_set_node_provision_state.delay(name, "provide")
|
114
|
-
|
115
|
-
elif object_data["previous_provision_state"] == "wait call-back":
|
116
|
-
pass
|
117
|
-
|
118
|
-
elif (
|
119
|
-
object_data["previous_provision_state"] == "cleaning"
|
120
|
-
and object_data["provision_state"] == "available"
|
121
|
-
): # noqa
|
122
|
-
# system should be in state c
|
123
|
-
netbox.connect.delay(name, "c")
|
124
|
-
|
125
|
-
elif event_type == "baremetal.port.create.end":
|
126
|
-
logger.info(f"baremetal.port.create.end ## {object_data['uuid']}")
|
127
|
-
|
128
|
-
mac_address = object_data["address"]
|
129
|
-
interface_a = utils.nb.dcim.interfaces.get(mac_address=mac_address)
|
130
|
-
device_a = interface_a.device
|
131
|
-
|
132
|
-
task = openstack.baremetal_get_network_interface_name.delay(
|
133
|
-
device_a.name, mac_address
|
134
|
-
)
|
135
|
-
task.wait(timeout=None, interval=0.5)
|
136
|
-
network_interface_name = task.get()
|
184
|
+
mac_address = object_data["address"]
|
185
|
+
interface_a = utils.nb.dcim.interfaces.get(mac_address=mac_address)
|
186
|
+
device_a = interface_a.device
|
137
187
|
|
138
|
-
|
139
|
-
|
140
|
-
|
188
|
+
task = openstack.baremetal_get_network_interface_name.delay(
|
189
|
+
device_a.name, mac_address
|
190
|
+
)
|
191
|
+
task.wait(timeout=None, interval=0.5)
|
192
|
+
network_interface_name = task.get()
|
141
193
|
|
142
|
-
|
143
|
-
|
194
|
+
netbox.update_network_interface_name.delay(
|
195
|
+
object_data["address"], network_interface_name
|
196
|
+
)
|
144
197
|
|
145
|
-
|
146
|
-
|
147
|
-
|
198
|
+
def node_delete_end(self, payload: dict[Any, Any]) -> None:
|
199
|
+
object_data = self.get_object_data(payload)
|
200
|
+
name = object_data["name"]
|
201
|
+
logger.info(f"baremetal.node.delete.end ## {name}")
|
148
202
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
203
|
+
netbox.set_state.delay(name, "unregistered", "ironic")
|
204
|
+
netbox.set_state.delay(name, None, "provision")
|
205
|
+
netbox.set_state.delay(name, None, "power")
|
206
|
+
netbox.set_state.delay(name, None, "introspection")
|
207
|
+
netbox.set_state.delay(name, None, "deployment")
|
154
208
|
|
155
|
-
|
156
|
-
|
157
|
-
)
|
209
|
+
# system should be in state a
|
210
|
+
netbox.connect.delay(name, "a")
|
158
211
|
|
159
|
-
|
160
|
-
|
212
|
+
# remove internal flavor
|
213
|
+
openstack.baremetal_delete_internal_flavor.delay(name)
|
161
214
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
215
|
+
def node_create_end(self, payload: dict[Any, Any]) -> None:
|
216
|
+
object_data = self.get_object_data(payload)
|
217
|
+
name = object_data["name"]
|
218
|
+
logger.info(f"baremetal.node.create.end ## {name}")
|
219
|
+
netbox.set_state.delay(name, "registered", "ironic")
|
167
220
|
|
168
|
-
# system should be in state a
|
169
|
-
netbox.connect.delay(name, "a")
|
170
221
|
|
171
|
-
|
172
|
-
|
222
|
+
class NotificationsDump(ConsumerMixin):
|
223
|
+
def __init__(self, connection):
|
224
|
+
self.connection = connection
|
225
|
+
self.baremetal_events = BaremetalEvents()
|
226
|
+
self.osism_api_session: None | requests.Session = None
|
227
|
+
self.osism_baremetal_api_url: None | str = None
|
228
|
+
if settings.OSISM_API_URL:
|
229
|
+
logger.info("Setting up OSISM API")
|
230
|
+
self.osism_api_session = requests.Session()
|
231
|
+
self.osism_baremetal_api_url = (
|
232
|
+
settings.OSISM_API_URL.rstrip("/") + "/notifications/baremetal"
|
233
|
+
)
|
234
|
+
return
|
235
|
+
|
236
|
+
def get_consumers(self, consumer, channel):
|
237
|
+
exchange = Exchange(EXCHANGE_NAME, type="topic", durable=False)
|
238
|
+
queue = Queue(
|
239
|
+
QUEUE_NAME,
|
240
|
+
exchange,
|
241
|
+
routing_key=ROUTING_KEY,
|
242
|
+
durable=False,
|
243
|
+
auto_delete=True,
|
244
|
+
no_ack=True,
|
245
|
+
)
|
246
|
+
return [consumer(queue, callbacks=[self.on_message])]
|
247
|
+
|
248
|
+
def on_message(self, body, message):
|
249
|
+
data = json.loads(body["oslo.message"])
|
250
|
+
# logger.info(data)
|
173
251
|
|
174
|
-
|
175
|
-
|
176
|
-
|
252
|
+
if self.osism_api_session:
|
253
|
+
tries = 1
|
254
|
+
max_tries = 3
|
255
|
+
while tries <= max_tries:
|
256
|
+
logger.info(
|
257
|
+
f"Trying to deliver notification to {self.osism_baremetal_api_url} (Try: {tries}/{max_tries})\n"
|
258
|
+
)
|
259
|
+
try:
|
260
|
+
response = self.osism_api_session.post(
|
261
|
+
self.osism_baremetal_api_url,
|
262
|
+
timeout=5,
|
263
|
+
json=dict(
|
264
|
+
priority=data["priority"],
|
265
|
+
event_type=data["event_type"],
|
266
|
+
timestamp=data["timestamp"],
|
267
|
+
publisher_id=data["publisher_id"],
|
268
|
+
message_id=data["message_id"],
|
269
|
+
payload=data["payload"],
|
270
|
+
),
|
271
|
+
)
|
272
|
+
if response.status_code == 204:
|
273
|
+
logger.info(
|
274
|
+
f"Successfully delivered notification to {self.osism_baremetal_api_url} (Try: {tries}/{max_tries})"
|
275
|
+
)
|
276
|
+
break
|
277
|
+
else:
|
278
|
+
response.raise_for_status()
|
279
|
+
except requests.ConnectionError:
|
280
|
+
logger.error(f"Error connecting to {self.osism_baremetal_api_url}")
|
281
|
+
except requests.Timeout:
|
282
|
+
logger.error(
|
283
|
+
f"Timeout reached while connecting to {self.osism_baremetal_api_url}"
|
284
|
+
)
|
285
|
+
except requests.HTTPError as e:
|
286
|
+
logger.error(
|
287
|
+
f"Received HTTP status code {e.response.status_code} while connecting to {self.osism_baremetal_api_url}"
|
288
|
+
)
|
289
|
+
if e.response.status_code <= 500:
|
290
|
+
logger.error(
|
291
|
+
f"Received HTTP status code {e.response.status_code} indicates a client side error, giving up early"
|
292
|
+
)
|
293
|
+
break
|
294
|
+
|
295
|
+
logger.error(
|
296
|
+
f"Failed to deliver notification to {self.osism_baremetal_api_url} ({tries}/{max_tries})"
|
297
|
+
)
|
298
|
+
tries += 1
|
299
|
+
if tries > max_tries:
|
300
|
+
logger.error(
|
301
|
+
f"Giving up delivering notification to {self.osism_baremetal_api_url} with data:\n"
|
302
|
+
+ json.dumps(data)
|
303
|
+
)
|
304
|
+
else:
|
305
|
+
time.sleep(pow(3, tries - 1))
|
177
306
|
|
178
307
|
else:
|
179
|
-
|
308
|
+
handler = self.baremetal_events.get_handler(data["event_type"])
|
309
|
+
handler(data["payload"])
|
180
310
|
|
181
|
-
logger.info(
|
311
|
+
logger.info(self.baremetal_events.get_object_data(data["payload"]))
|
182
312
|
|
183
313
|
|
184
314
|
def main():
|
osism/settings.py
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
janhorstmann <horstmann@osism.tech>
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: osism
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.20250312.0
|
4
4
|
Summary: OSISM manager interface
|
5
5
|
Home-page: https://github.com/osism/python-osism
|
6
6
|
Author: OSISM GmbH
|
@@ -22,46 +22,54 @@ Requires-Python: >=3.8
|
|
22
22
|
Description-Content-Type: text/markdown
|
23
23
|
License-File: LICENSE
|
24
24
|
License-File: AUTHORS
|
25
|
-
Requires-Dist: ClusterShell==1.9.
|
26
|
-
Requires-Dist: GitPython==3.1.
|
27
|
-
Requires-Dist: Jinja2==3.1.
|
25
|
+
Requires-Dist: ClusterShell==1.9.3
|
26
|
+
Requires-Dist: GitPython==3.1.44
|
27
|
+
Requires-Dist: Jinja2==3.1.6
|
28
28
|
Requires-Dist: PyYAML==6.0.2
|
29
29
|
Requires-Dist: ara==1.7.2
|
30
30
|
Requires-Dist: celery[redis]==5.4.0
|
31
|
-
Requires-Dist: cliff==4.
|
32
|
-
Requires-Dist: deepdiff==8.
|
31
|
+
Requires-Dist: cliff==4.9.1
|
32
|
+
Requires-Dist: deepdiff==8.3.0
|
33
33
|
Requires-Dist: docker==7.1.0
|
34
|
-
Requires-Dist: dtrack-auditor==1.
|
35
|
-
Requires-Dist: fastapi==0.115.
|
34
|
+
Requires-Dist: dtrack-auditor==1.5.0
|
35
|
+
Requires-Dist: fastapi==0.115.11
|
36
36
|
Requires-Dist: flower==2.0.1
|
37
37
|
Requires-Dist: hiredis==3.1.0
|
38
38
|
Requires-Dist: jc==1.25.4
|
39
|
-
Requires-Dist: keystoneauth1==5.
|
39
|
+
Requires-Dist: keystoneauth1==5.10.0
|
40
40
|
Requires-Dist: kombu==5.4.2
|
41
|
-
Requires-Dist: kubernetes==
|
41
|
+
Requires-Dist: kubernetes==32.0.1
|
42
42
|
Requires-Dist: loguru==0.7.3
|
43
43
|
Requires-Dist: netmiko==4.5.0
|
44
44
|
Requires-Dist: nornir-ansible==2023.12.28
|
45
|
-
Requires-Dist: nornir==3.
|
45
|
+
Requires-Dist: nornir==3.5.0
|
46
46
|
Requires-Dist: openstacksdk==4.2.0
|
47
47
|
Requires-Dist: pottery==3.0.0
|
48
|
-
Requires-Dist: prompt-toolkit==3.0.
|
49
|
-
Requires-Dist: pydantic==1.10.
|
48
|
+
Requires-Dist: prompt-toolkit==3.0.50
|
49
|
+
Requires-Dist: pydantic==1.10.21
|
50
50
|
Requires-Dist: pynetbox==7.4.1
|
51
51
|
Requires-Dist: pytest-testinfra==10.1.1
|
52
52
|
Requires-Dist: python-dateutil==2.9.0.post0
|
53
|
-
Requires-Dist: setuptools==
|
54
|
-
Requires-Dist: sqlmodel==0.0.
|
55
|
-
Requires-Dist: sushy==5.
|
53
|
+
Requires-Dist: setuptools==76.0.0
|
54
|
+
Requires-Dist: sqlmodel==0.0.24
|
55
|
+
Requires-Dist: sushy==5.5.0
|
56
56
|
Requires-Dist: tabulate==0.9.0
|
57
57
|
Requires-Dist: transitions==0.9.2
|
58
58
|
Requires-Dist: uvicorn[standard]==0.34.0
|
59
59
|
Requires-Dist: watchdog==6.0.0
|
60
60
|
Provides-Extra: ansible
|
61
61
|
Requires-Dist: ansible-runner==2.4.0; extra == "ansible"
|
62
|
-
Requires-Dist: ansible-core==2.18.
|
62
|
+
Requires-Dist: ansible-core==2.18.3; extra == "ansible"
|
63
63
|
Provides-Extra: openstack-image-manager
|
64
64
|
Requires-Dist: openstack-image-manager==0.20241216.0; extra == "openstack-image-manager"
|
65
|
+
Dynamic: author
|
66
|
+
Dynamic: author-email
|
67
|
+
Dynamic: classifier
|
68
|
+
Dynamic: description
|
69
|
+
Dynamic: home-page
|
70
|
+
Dynamic: requires-dist
|
71
|
+
Dynamic: requires-python
|
72
|
+
Dynamic: summary
|
65
73
|
|
66
74
|
# python-osism
|
67
75
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
osism/__init__.py,sha256=1UiNTBus0V0f2AbZQzAtVtu6zkfCCrw0OTq--NwFAqY,341
|
2
2
|
osism/__main__.py,sha256=ILe4gu61xEISiBsxanqTQIdSkV-YhpZXTRlguCYyssk,141
|
3
|
-
osism/api.py,sha256=
|
3
|
+
osism/api.py,sha256=X3IVLWbKMtfozJ5sEx6sLEZ1rD4U9s3uNnLLwxiwDjs,4802
|
4
4
|
osism/main.py,sha256=Dt2-9sLXcS-Ny4DAz7hrha-KRc7zd7BFUTRdfs_X8z4,893
|
5
|
-
osism/settings.py,sha256=
|
5
|
+
osism/settings.py,sha256=cv0vxsBNinCUAfAXANuQ1-W3YIRv6BWWwcdO5Y6HGko,1165
|
6
6
|
osism/actions/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
|
7
7
|
osism/actions/check_configuration.py,sha256=f_nwMsMh9G1z8tmxSoDGyWoFtI1NLVWks70fknY5st0,1301
|
8
8
|
osism/actions/deploy_configuration.py,sha256=uHrW6J0908zloK3SnOcKq3m53H8KCihplU1IA10mZMA,2712
|
@@ -40,7 +40,7 @@ osism/core/playbooks.py,sha256=M3T3ajV-8Lt-orsRO3jAoukhaoYFr4EZ2dzYXQjt1kg,728
|
|
40
40
|
osism/data/__init__.py,sha256=izXdh0J3vPLQI7kBhJI7ibJQzPqU_nlONP0L4Cf_k6A,1504
|
41
41
|
osism/plugins/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
|
42
42
|
osism/services/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
|
43
|
-
osism/services/listener.py,sha256
|
43
|
+
osism/services/listener.py,sha256=-oknzaroJxpWzaeilkJnyxNUj_EF1q7zJGAexMP0YVY,12695
|
44
44
|
osism/tasks/__init__.py,sha256=DHV40JwT0gSQrpjgT6AtxO-HBxBm1fexRNGUqbmFQZU,8556
|
45
45
|
osism/tasks/ansible.py,sha256=0c5nY1M0jf_9Me8HMP2Je_Ibjii4rFm-5HW8tmE6aos,1681
|
46
46
|
osism/tasks/ceph.py,sha256=eIQkah3Kj4INtOkF9kTjHbXJ3_J2lg48EWJKfHc-UYw,615
|
@@ -51,11 +51,11 @@ osism/tasks/netbox.py,sha256=a2g0iwuODCbptzjBXtwHNUpSpQxQRF9wCGE8JBZWVO0,6596
|
|
51
51
|
osism/tasks/openstack.py,sha256=i9dIVz9RPVC38gIhUPIE0oq8Wj2ppf9bHrHLTrsjaJ8,9098
|
52
52
|
osism/tasks/reconciler.py,sha256=RpepZtRgBgYTwmAkfuT9kIaxU1ITDb8SFalMoShdRNQ,3547
|
53
53
|
osism/utils/__init__.py,sha256=5yng8l5Jd6GhNO4FNi6iYH4569UuTYAynamANgZnm1E,1258
|
54
|
-
osism-0.
|
55
|
-
osism-0.
|
56
|
-
osism-0.
|
57
|
-
osism-0.
|
58
|
-
osism-0.
|
59
|
-
osism-0.
|
60
|
-
osism-0.
|
61
|
-
osism-0.
|
54
|
+
osism-0.20250312.0.dist-info/AUTHORS,sha256=DJIRsjyrFxKjFvmpUNDRDBS04nRiJ5B6FpKcDcfnoGM,36
|
55
|
+
osism-0.20250312.0.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
|
56
|
+
osism-0.20250312.0.dist-info/METADATA,sha256=_PV0PsInCReaFHooi_DST5yYtlATeDgas34bajssFZ8,2950
|
57
|
+
osism-0.20250312.0.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
58
|
+
osism-0.20250312.0.dist-info/entry_points.txt,sha256=Hjy0x6duRr78IEPd2oHi-P0LWWIe85zgX9DwovKYNbM,3408
|
59
|
+
osism-0.20250312.0.dist-info/pbr.json,sha256=GBO14uGezrRoQuN7HmabA-K5ph_U6W95Po1XXDzI-zU,47
|
60
|
+
osism-0.20250312.0.dist-info/top_level.txt,sha256=8L8dsI9hcaGHsdnR4k_LN9EM78EhwrXRFHyAryPXZtY,6
|
61
|
+
osism-0.20250312.0.dist-info/RECORD,,
|
@@ -0,0 +1 @@
|
|
1
|
+
{"git_version": "314593e", "is_release": false}
|
@@ -1 +0,0 @@
|
|
1
|
-
Christian Berendt <berendt@osism.tech>
|
@@ -1 +0,0 @@
|
|
1
|
-
{"git_version": "e14566d", "is_release": false}
|
File without changes
|
File without changes
|
File without changes
|