osism 0.20250219.0__py3-none-any.whl → 0.20250314.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,
osism/commands/netbox.py CHANGED
@@ -1,16 +1,13 @@
1
1
  # SPDX-License-Identifier: Apache-2.0
2
2
 
3
3
  import argparse
4
- from glob import glob
5
- from os.path import basename
6
4
 
7
5
  from cliff.command import Command
8
6
  from loguru import logger
9
7
  from redis import Redis
10
- from tabulate import tabulate
11
8
 
12
9
  from osism import settings
13
- from osism.tasks import conductor, netbox, reconciler, ansible, openstack, handle_task
10
+ from osism.tasks import conductor, netbox, reconciler, openstack, handle_task
14
11
 
15
12
 
16
13
  redis = Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=settings.REDIS_DB)
@@ -77,368 +74,82 @@ class Sync(Command):
77
74
  task.wait(timeout=None, interval=0.5)
78
75
 
79
76
 
80
- class Init(Command):
81
- def get_parser(self, prog_name):
82
- parser = super(Init, self).get_parser(prog_name)
83
- parser.add_argument(
84
- "arguments", nargs=argparse.REMAINDER, help="Other arguments for Ansible"
85
- )
86
- parser.add_argument(
87
- "--no-wait",
88
- default=False,
89
- help="Do not wait until the role has been applied",
90
- action="store_true",
91
- )
92
- parser.add_argument(
93
- "--format",
94
- default="log",
95
- help="Output type",
96
- const="log",
97
- nargs="?",
98
- choices=["script", "log"],
99
- ),
100
- return parser
101
-
102
- def take_action(self, parsed_args):
103
- arguments = parsed_args.arguments
104
- format = parsed_args.format
105
- wait = not parsed_args.no_wait
106
-
107
- task = ansible.run.delay("netbox-local", "init", arguments)
108
- rc = 0
109
-
110
- if wait:
111
- logger.info(f"Task {task.task_id} was prepared for execution.")
112
- logger.info(
113
- f"It takes a moment until task {task.task_id} has been started and output is visible here."
114
- )
115
- rc = handle_task(task, wait, format, 300)
116
- else:
117
- logger.info(
118
- f"Task {task.task_id} is running in background. No more output. Check ARA for logs."
119
- )
120
-
121
- return rc
122
-
123
-
124
- class Import(Command):
125
- def get_parser(self, prog_name):
126
- parser = super(Import, self).get_parser(prog_name)
127
- parser.add_argument(
128
- "--vendors",
129
- help="Vendors from which all available device types are to be imported",
130
- required=False,
131
- )
132
- parser.add_argument(
133
- "--library",
134
- default=False,
135
- help="Do import device types from the device type library",
136
- action="store_true",
137
- )
138
- parser.add_argument(
139
- "--no-wait",
140
- default=False,
141
- help="Do not wait until the role has been applied",
142
- action="store_true",
143
- )
144
- return parser
145
-
146
- def take_action(self, parsed_args):
147
- vendors = parsed_args.vendors
148
- wait = not parsed_args.no_wait
149
-
150
- task = netbox.import_device_types.delay(vendors, parsed_args.library)
151
-
152
- if wait:
153
- logger.info(f"Task {task.task_id} is running. Wait. No more output.")
154
- task.wait(timeout=None, interval=0.5)
155
-
156
-
157
77
  class Manage(Command):
158
78
  def get_parser(self, prog_name):
159
79
  parser = super(Manage, self).get_parser(prog_name)
160
- parser.add_argument(
161
- "--type",
162
- type=str,
163
- help="Type of the resource to manage",
164
- required=False,
165
- default="rack",
166
- )
167
- parser.add_argument(
168
- "name", nargs="?", type=str, help="Name of the resource to manage"
169
- )
170
- parser.add_argument(
171
- "arguments", nargs=argparse.REMAINDER, help="Other arguments for Ansible"
172
- )
173
80
  parser.add_argument(
174
81
  "--no-wait",
175
82
  default=False,
176
- help="Do not wait until the changes have been made",
83
+ help="Do not wait until the management of the netbox has been completed",
177
84
  action="store_true",
178
85
  )
179
86
  parser.add_argument(
180
- "--format",
181
- default="log",
182
- help="Output type",
183
- const="log",
184
- nargs="?",
185
- choices=["script", "log"],
186
- ),
187
- return parser
188
-
189
- def take_action(self, parsed_args):
190
- arguments = parsed_args.arguments
191
- format = parsed_args.format
192
- name = parsed_args.name
193
- type_of_resource = parsed_args.type
194
- wait = not parsed_args.no_wait
195
-
196
- rc = 0
197
- if not name:
198
- logger.info("No name of an object to be managed was given")
199
- table = []
200
- for playbook_type in ["rack"]:
201
- playbooks = glob(
202
- f"/opt/configuration/netbox/playbooks/{playbook_type}-*.yml"
203
- )
204
- for playbook in playbooks:
205
- name = basename(playbook)[len(playbook_type) + 1 : -4] # noqa E203
206
- table.append([playbook_type, name])
207
-
208
- print(tabulate(table, headers=["Type", "Name"], tablefmt="psql"))
209
- else:
210
- task = ansible.run.delay(
211
- "netbox-local", f"{type_of_resource}-{name}", arguments
212
- )
213
-
214
- if wait:
215
- logger.info(f"Task {task.task_id} was prepared for execution.")
216
- logger.info(
217
- f"It takes a moment until task {task.task_id} has been started and output is visible here."
218
- )
219
- rc = handle_task(task, wait, format, 300)
220
- else:
221
- logger.info(
222
- f"Task {task.task_id} is running in background. No more output. Check ARA for logs."
223
- )
224
-
225
- return rc
226
-
227
-
228
- class Connect(Command):
229
- def get_parser(self, prog_name):
230
- parser = super(Connect, self).get_parser(prog_name)
231
- parser.add_argument(
232
- "name",
233
- nargs="?",
234
- type=str,
235
- help="Name of the resource (a collection or a device) to connect",
236
- )
237
- parser.add_argument(
238
- "--collection",
239
- type=str,
240
- help="Name of the collection to connect",
241
- required=False,
242
- ),
243
- parser.add_argument(
244
- "--device", type=str, help="Name of the device to connect", required=False
245
- )
246
- parser.add_argument(
247
- "--enforce",
87
+ "--no-netbox-wait",
248
88
  default=False,
249
- help="Ignore the current transition of a device",
89
+ help="Do not wait for the netbox API to be ready",
250
90
  action="store_true",
251
91
  )
252
92
  parser.add_argument(
253
- "--state", type=str, help="State to use", default=None, required=False
254
- )
255
- parser.add_argument(
256
- "--type",
257
- type=str,
258
- default="collection",
259
- help="Type of the resource to connection (when not using --collection or --device)",
260
- required=False,
261
- )
262
- return parser
263
-
264
- def take_action(self, parsed_args):
265
- name = parsed_args.name
266
- collection = parsed_args.device
267
- device = parsed_args.device
268
- state = parsed_args.state
269
- type_of_resource = parsed_args.type
270
- enforce = parsed_args.enforce
271
-
272
- task = None
273
-
274
- if name:
275
- if type_of_resource == "collection":
276
- task = netbox.data.delay(name, "", state)
277
- elif type_of_resource == "device":
278
- task = netbox.data.delay("", name, state)
279
- else:
280
- task = netbox.data.delay(collection, device, state)
281
- name = f"{collection}-{device}"
282
-
283
- task.wait(timeout=None, interval=0.5)
284
- data = task.get()
285
-
286
- for device in data:
287
- t = netbox.connect.delay(device, state, data, enforce)
288
- logger.info(
289
- f"Task {t.task_id} for device {device} is running in background"
290
- )
291
- logger.info(
292
- "Tasks are running in background. No more output. Check Flower for logs."
293
- )
294
-
295
-
296
- class Disable(Command):
297
- def get_parser(self, prog_name):
298
- parser = super(Disable, self).get_parser(prog_name)
299
- parser.add_argument(
300
- "name",
301
- nargs=1,
93
+ "--limit",
302
94
  type=str,
303
- help="Name of the device to check for unused interfaces",
95
+ default=None,
96
+ help="Limit files by prefix",
304
97
  )
305
98
  parser.add_argument(
306
- "--no-wait",
99
+ "--skipdtl",
307
100
  default=False,
308
- help="Do not wait until the changes have been made",
101
+ help="Skip devicetype library",
309
102
  action="store_true",
310
103
  )
311
- return parser
312
-
313
- def take_action(self, parsed_args):
314
- name = parsed_args.name[0]
315
- wait = not parsed_args.no_wait
316
-
317
- task = netbox.disable.delay(name)
318
-
319
- if wait:
320
- logger.info(f"Task {task.task_id} is running. Wait. No more output.")
321
- task.wait(timeout=None, interval=0.5)
322
-
323
-
324
- class Generate(Command):
325
- def get_parser(self, prog_name):
326
- parser = super(Generate, self).get_parser(prog_name)
327
104
  parser.add_argument(
328
- "name",
329
- nargs=1,
330
- type=str,
331
- help="Name of the device for which the configuration is to be generated.",
332
- )
333
- parser.add_argument(
334
- "--no-wait",
105
+ "--skipmtl",
335
106
  default=False,
336
- help="Do not wait until the changes have been made",
107
+ help="Skip moduletype library",
337
108
  action="store_true",
338
109
  )
339
110
  parser.add_argument(
340
- "--template", type=str, help="Name of the template to use", required=False
341
- )
342
- return parser
343
-
344
- def take_action(self, parsed_args):
345
- name = parsed_args.name[0]
346
- template = parsed_args.template
347
- wait = not parsed_args.no_wait
348
-
349
- task = netbox.generate.delay(name, template)
350
-
351
- if wait:
352
- logger.info(f"Task {task.task_id} is running. Wait. No more output.")
353
- task.wait(timeout=None, interval=0.5)
354
-
355
-
356
- class Deploy(Command):
357
- def get_parser(self, prog_name):
358
- parser = super(Deploy, self).get_parser(prog_name)
359
- parser.add_argument(
360
- "name",
361
- nargs=1,
362
- type=str,
363
- help="Name of the device for which the configuration is to be deployed",
364
- )
365
- parser.add_argument(
366
- "arguments", nargs=argparse.REMAINDER, help="Other arguments for Ansible"
367
- )
368
- parser.add_argument(
369
- "--no-wait",
111
+ "--skipres",
370
112
  default=False,
371
- help="Do not wait until the changes have been made",
113
+ help="Skip resources",
372
114
  action="store_true",
373
115
  )
374
116
  return parser
375
117
 
376
118
  def take_action(self, parsed_args):
377
- name = parsed_args.name[0]
378
- # arguments = parsed_args.arguments
379
119
  wait = not parsed_args.no_wait
120
+ arguments = []
380
121
 
381
- task = netbox.deploy.delay(name)
382
-
383
- if wait:
384
- logger.info(f"Task {task.task_id} is running. Wait. No more output.")
385
- task.wait(timeout=None, interval=0.5)
122
+ if parsed_args.no_netbox_wait:
123
+ arguments.append("--no-wait")
124
+ else:
125
+ arguments.append("--wait")
386
126
 
127
+ if parsed_args.limit:
128
+ arguments.append("--limit {parsed_args.limit}")
387
129
 
388
- class Check(Command):
389
- def get_parser(self, prog_name):
390
- parser = super(Check, self).get_parser(prog_name)
391
- parser.add_argument(
392
- "name",
393
- nargs=1,
394
- type=str,
395
- help="Name of the device for which the configuration is to be checked",
396
- )
397
- parser.add_argument(
398
- "--no-wait",
399
- default=False,
400
- help="Do not wait until the changes have been made",
401
- action="store_true",
402
- )
403
- return parser
130
+ if parsed_args.skipdtl:
131
+ arguments.append("--skipdtl")
132
+ else:
133
+ arguments.append("--no-skipdtl")
404
134
 
405
- def take_action(self, parsed_args):
406
- name = parsed_args.name[0]
407
- wait = not parsed_args.no_wait
135
+ if parsed_args.skipmtl:
136
+ arguments.append("--skipmtl")
137
+ else:
138
+ arguments.append("--no-skipmtl")
408
139
 
409
- task = netbox.check.delay(name)
140
+ if parsed_args.skipres:
141
+ arguments.append("--skipres")
142
+ else:
143
+ arguments.append("--no-skipres")
410
144
 
145
+ task_signature = netbox.manage.si(*arguments)
146
+ task = task_signature.apply_async()
411
147
  if wait:
412
- logger.info(f"Task {task.task_id} is running. Wait. No more output.")
413
- task.wait(timeout=None, interval=0.5)
414
-
415
-
416
- class Diff(Command):
417
- def get_parser(self, prog_name):
418
- parser = super(Diff, self).get_parser(prog_name)
419
- parser.add_argument(
420
- "name",
421
- nargs=1,
422
- type=str,
423
- help="Name of the device for which the configuration is to be diffed",
424
- )
425
- parser.add_argument(
426
- "--no-wait",
427
- default=False,
428
- help="Do not wait until the changes have been made",
429
- action="store_true",
430
- )
431
- return parser
432
-
433
- def take_action(self, parsed_args):
434
- name = parsed_args.name[0]
435
- wait = not parsed_args.no_wait
436
-
437
- task = netbox.diff.delay(name)
148
+ logger.info(
149
+ f"It takes a moment until task {task.task_id} (netbox-manager) has been started and output is visible here."
150
+ )
438
151
 
439
- if wait:
440
- logger.info(f"Task {task.task_id} is running. Wait. No more output.")
441
- task.wait(timeout=None, interval=0.5)
152
+ return handle_task(task, wait, format="script", timeout=3600)
442
153
 
443
154
 
444
155
  class Ping(Command):