osism 0.20250219.0__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 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,
@@ -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 NotificationsDump(ConsumerMixin):
21
- def __init__(self, connection):
22
- self.connection = connection
23
- return
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
- def get_consumers(self, consumer, channel):
26
- exchange = Exchange(EXCHANGE_NAME, type="topic", durable=False)
27
- queue = Queue(
28
- QUEUE_NAME,
29
- exchange,
30
- routing_key=ROUTING_KEY,
31
- durable=False,
32
- auto_delete=True,
33
- no_ack=True,
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
- return [consumer(queue, callbacks=[self.on_message])]
82
+ netbox.set_state.delay(name, object_data["power_state"], "power")
36
83
 
37
- def on_message(self, body, message):
38
- data = json.loads(body["oslo.message"])
39
- # logger.info(data)
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
- event_type = data["event_type"]
42
- payload = data["payload"]
43
- object_data = payload["ironic_object.data"]
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
- # References:
48
- #
49
- # * https://docs.openstack.org/ironic/latest/admin/notifications.html#available-notifications
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 event_type == "baremetal.node.power_set.end":
54
- logger.info(
55
- f"baremetal.node.power_set.end ## {name} ## {object_data['power_state']}"
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
- elif event_type == "baremetal.node.power_state_corrected.success":
60
- logger.info(
61
- f"baremetal.node.power_state_corrected.success ## {name} ## {object_data['power_state']}"
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
- elif event_type == "baremetal.node.maintenance_set.end":
66
- logger.info(
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
- elif event_type == "baremetal.node.provision_set.start":
72
- logger.info(
73
- f"baremetal.node.provision_set.start ## {name} ## {object_data['provision_state']}"
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
- if object_data["event"] == "inspect":
77
- # system should be in state a
78
- netbox.connect.delay(name, "a")
131
+ if object_data["provision_state"] == "manageable":
132
+ # system should be in state c
133
+ netbox.connect.delay(name, "c")
79
134
 
80
- if object_data["provision_state"] == "cleaning":
81
- # system should be in state b
82
- netbox.connect.delay(name, "b")
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
- if object_data["provision_state"] == "available":
85
- # system should be in state c
86
- netbox.connect.delay(name, "c")
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
- if object_data["target_provision_state"] == "active":
89
- pass
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
- # A provision status was successfully set, update it in the netbox
92
- elif event_type == "baremetal.node.provision_set.success":
93
- logger.info(
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
- if object_data["provision_state"] == "manageable":
99
- # system should be in state c
100
- netbox.connect.delay(name, "c")
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
- elif event_type == "baremetal.node.provision_set.end":
103
- logger.info(
104
- f"baremetal.node.provision_set.end ## {name} ## {object_data['provision_state']}"
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
- netbox.update_network_interface_name.delay(
139
- object_data["address"], network_interface_name
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
- elif event_type == "baremetal.port.update.end":
143
- logger.info(f"baremetal.port.update.end ## {object_data['uuid']}")
194
+ netbox.update_network_interface_name.delay(
195
+ object_data["address"], network_interface_name
196
+ )
144
197
 
145
- mac_address = object_data["address"]
146
- interface_a = utils.nb.dcim.interfaces.get(mac_address=mac_address)
147
- device_a = interface_a.device
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
- task = openstack.baremetal_get_network_interface_name.delay(
150
- device_a.name, mac_address
151
- )
152
- task.wait(timeout=None, interval=0.5)
153
- network_interface_name = task.get()
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
- netbox.update_network_interface_name.delay(
156
- object_data["address"], network_interface_name
157
- )
209
+ # system should be in state a
210
+ netbox.connect.delay(name, "a")
158
211
 
159
- elif event_type == "baremetal.node.delete.end":
160
- logger.info(f"baremetal.node.delete.end ## {name}")
212
+ # remove internal flavor
213
+ openstack.baremetal_delete_internal_flavor.delay(name)
161
214
 
162
- netbox.set_state.delay(name, "unregistered", "ironic")
163
- netbox.set_state.delay(name, None, "provision")
164
- netbox.set_state.delay(name, None, "power")
165
- netbox.set_state.delay(name, None, "introspection")
166
- netbox.set_state.delay(name, None, "deployment")
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
- # remove internal flavor
172
- openstack.baremetal_delete_internal_flavor.delay(name)
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
- elif event_type == "baremetal.node.create.end":
175
- logger.info(f"baremetal.node.create.end ## {name}")
176
- netbox.set_state.delay(name, "registered", "ironic")
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
- logger.info(f"{event_type} ## {name}")
308
+ handler = self.baremetal_events.get_handler(data["event_type"])
309
+ handler(data["payload"])
180
310
 
181
- logger.info(object_data)
311
+ logger.info(self.baremetal_events.get_object_data(data["payload"]))
182
312
 
183
313
 
184
314
  def main():
osism/settings.py CHANGED
@@ -35,3 +35,5 @@ GATHER_FACTS_SCHEDULE = float(os.getenv("GATHER_FACTS_SCHEDULE", "43200.0"))
35
35
  INVENTORY_RECONCILER_SCHEDULE = float(
36
36
  os.getenv("INVENTORY_RECONCILER_SCHEDULE", "600.0")
37
37
  )
38
+
39
+ OSISM_API_URL = os.getenv("OSISM_API_URL", None)
@@ -0,0 +1 @@
1
+ janhorstmann <horstmann@osism.tech>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: osism
3
- Version: 0.20250219.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
@@ -24,21 +24,21 @@ License-File: LICENSE
24
24
  License-File: AUTHORS
25
25
  Requires-Dist: ClusterShell==1.9.3
26
26
  Requires-Dist: GitPython==3.1.44
27
- Requires-Dist: Jinja2==3.1.5
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.8.0
32
- Requires-Dist: deepdiff==8.2.0
31
+ Requires-Dist: cliff==4.9.1
32
+ Requires-Dist: deepdiff==8.3.0
33
33
  Requires-Dist: docker==7.1.0
34
34
  Requires-Dist: dtrack-auditor==1.5.0
35
- Requires-Dist: fastapi==0.115.7
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.9.1
39
+ Requires-Dist: keystoneauth1==5.10.0
40
40
  Requires-Dist: kombu==5.4.2
41
- Requires-Dist: kubernetes==32.0.0
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
@@ -50,16 +50,16 @@ 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==75.8.0
54
- Requires-Dist: sqlmodel==0.0.22
55
- Requires-Dist: sushy==5.4.0
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.2; extra == "ansible"
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
65
  Dynamic: author
@@ -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=xI55lHQVubm5q7esvNITBAK63Pw2IJl6zQyXjjfHk-Y,4313
3
+ osism/api.py,sha256=X3IVLWbKMtfozJ5sEx6sLEZ1rD4U9s3uNnLLwxiwDjs,4802
4
4
  osism/main.py,sha256=Dt2-9sLXcS-Ny4DAz7hrha-KRc7zd7BFUTRdfs_X8z4,893
5
- osism/settings.py,sha256=v8PK-xofJYR4uVuW8e2stxI_oz6Whoe4JGEWG3M58z8,1115
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=w7iAuBD5wAUDT-3Ztf9ThDxuQNgobs1tTGYythsA800,7218
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.20250219.0.dist-info/AUTHORS,sha256=oWotd63qsnNR945QLJP9mEXaXNtCMaesfo8ZNuLjwpU,39
55
- osism-0.20250219.0.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
56
- osism-0.20250219.0.dist-info/METADATA,sha256=s2NNBLNJyGTezm6Nx5zZTM4GosrFYYIsyMPp_esAkJ4,2948
57
- osism-0.20250219.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
58
- osism-0.20250219.0.dist-info/entry_points.txt,sha256=Hjy0x6duRr78IEPd2oHi-P0LWWIe85zgX9DwovKYNbM,3408
59
- osism-0.20250219.0.dist-info/pbr.json,sha256=_vVXipaqRou9NFlGplx2oPWjiksk1Y2L94Fqu3QuYuk,47
60
- osism-0.20250219.0.dist-info/top_level.txt,sha256=8L8dsI9hcaGHsdnR4k_LN9EM78EhwrXRFHyAryPXZtY,6
61
- osism-0.20250219.0.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (76.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -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": "6615081", "is_release": false}