osism 0.20250326.0__py3-none-any.whl → 0.20250331.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
@@ -11,7 +11,7 @@ import pynetbox
11
11
  from starlette.middleware.cors import CORSMiddleware
12
12
 
13
13
  from osism.tasks import reconciler
14
- from osism import settings
14
+ from osism import settings, utils
15
15
  from osism.services.listener import BaremetalEvents
16
16
 
17
17
 
@@ -75,16 +75,13 @@ app.add_middleware(CORSMiddleware)
75
75
  dictConfig(LogConfig().dict())
76
76
  logger = logging.getLogger("api")
77
77
 
78
- nb = None
79
78
  baremetal_events = BaremetalEvents()
80
79
 
81
80
 
82
81
  @app.on_event("startup")
83
82
  async def startup_event():
84
- global nb
85
-
86
83
  if settings.NETBOX_URL and settings.NETBOX_TOKEN:
87
- nb = pynetbox.api(settings.NETBOX_URL, token=settings.NETBOX_TOKEN)
84
+ utils.nb = pynetbox.api(settings.NETBOX_URL, token=settings.NETBOX_TOKEN)
88
85
 
89
86
  if settings.IGNORE_SSL_ERRORS:
90
87
  import requests
@@ -92,7 +89,7 @@ async def startup_event():
92
89
  requests.packages.urllib3.disable_warnings()
93
90
  session = requests.Session()
94
91
  session.verify = False
95
- nb.http_session = session
92
+ utils.nb.http_session = session
96
93
 
97
94
 
98
95
  @app.get("/")
@@ -125,9 +122,7 @@ async def webhook(
125
122
  content_length: int = Header(...),
126
123
  x_hook_signature: str = Header(None),
127
124
  ):
128
- global nb
129
-
130
- if nb:
125
+ if utils.nb:
131
126
  data = webhook_input.data
132
127
  url = data["url"]
133
128
  name = data["name"]
@@ -146,7 +141,7 @@ async def webhook(
146
141
  device_type = "interface"
147
142
 
148
143
  device_id = data["device"]["id"]
149
- device = nb.dcim.devices.get(id=device_id)
144
+ device = utils.nb.dcim.devices.get(id=device_id)
150
145
  tags = [str(x) for x in device.tags]
151
146
  custom_fields = device.custom_fields
152
147
 
osism/commands/netbox.py CHANGED
@@ -2,16 +2,10 @@
2
2
 
3
3
  from cliff.command import Command
4
4
  from loguru import logger
5
- from redis import Redis
6
5
 
7
- from osism import settings
8
6
  from osism.tasks import conductor, netbox, reconciler, openstack, handle_task
9
7
 
10
8
 
11
- redis = Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=settings.REDIS_DB)
12
- redis.ping()
13
-
14
-
15
9
  class Ironic(Command):
16
10
  def get_parser(self, prog_name):
17
11
  parser = super(Ironic, self).get_parser(prog_name)
osism/commands/wait.py CHANGED
@@ -6,8 +6,7 @@ from celery import Celery
6
6
  from celery.result import AsyncResult
7
7
  from cliff.command import Command
8
8
  from loguru import logger
9
- from redis import Redis
10
- from osism import settings
9
+ from osism import utils
11
10
  from osism.tasks import Config
12
11
 
13
12
 
@@ -119,18 +118,12 @@ class Run(Command):
119
118
  print(f"{task_id} = STARTED")
120
119
 
121
120
  if live:
122
- redis = Redis(
123
- host=settings.REDIS_HOST,
124
- port=settings.REDIS_PORT,
125
- db=settings.REDIS_DB,
126
- socket_keepalive=True,
127
- )
128
- redis.ping()
121
+ utils.redis.ping()
129
122
 
130
123
  last_id = 0
131
124
  while_True = True
132
125
  while while_True:
133
- data = redis.xread(
126
+ data = utils.redis.xread(
134
127
  {str(task_id): last_id}, count=1, block=1000
135
128
  )
136
129
  if data:
@@ -143,7 +136,7 @@ class Run(Command):
143
136
  logger.debug(
144
137
  f"Processing message {last_id} of type {message_type}"
145
138
  )
146
- redis.xdel(str(task_id), last_id)
139
+ utils.redis.xdel(str(task_id), last_id)
147
140
 
148
141
  if message_type == "stdout":
149
142
  print(message_content, end="")
@@ -153,7 +146,7 @@ class Run(Command):
153
146
  message_type == "action"
154
147
  and message_content == "quit"
155
148
  ):
156
- redis.close()
149
+ utils.redis.close()
157
150
  if len(task_ids) == 1:
158
151
  return rc
159
152
  else:
osism/core/enums.py CHANGED
@@ -107,6 +107,7 @@ VALIDATE_PLAYBOOKS = {
107
107
  "ntp": {"environment": "generic", "runtime": "osism-ansible"},
108
108
  "system-encoding": {"environment": "generic", "runtime": "osism-ansible"},
109
109
  "ulimits": {"environment": "generic", "runtime": "osism-ansible"},
110
+ "stress": {"environment": "generic", "runtime": "osism-ansible"},
110
111
  }
111
112
 
112
113
  MAP_ROLE2ROLE = {
osism/tasks/__init__.py CHANGED
@@ -5,14 +5,10 @@ import re
5
5
  import subprocess
6
6
  import time
7
7
 
8
- from celery.signals import worker_process_init
9
8
  from loguru import logger
10
- from redis import Redis
11
9
  from pottery import Redlock
12
10
 
13
- from osism import settings
14
-
15
- redis = None
11
+ from osism import utils
16
12
 
17
13
 
18
14
  class Config:
@@ -36,19 +32,6 @@ class Config:
36
32
  }
37
33
 
38
34
 
39
- @worker_process_init.connect
40
- def celery_init_worker(**kwargs):
41
- global redis
42
-
43
- redis = Redis(
44
- host=settings.REDIS_HOST,
45
- port=settings.REDIS_PORT,
46
- db=settings.REDIS_DB,
47
- socket_keepalive=True,
48
- )
49
- redis.ping()
50
-
51
-
52
35
  def run_ansible_in_environment(
53
36
  request_id,
54
37
  worker,
@@ -88,7 +71,7 @@ def run_ansible_in_environment(
88
71
 
89
72
  # NOTE: This is a first step to make Ansible Vault usable via OSISM workers.
90
73
  # It's not ready in that form yet.
91
- ansible_vault_password = redis.get("ansible_vault_password")
74
+ ansible_vault_password = utils.redis.get("ansible_vault_password")
92
75
  if ansible_vault_password:
93
76
  env["VAULT"] = "/ansible-vault.py"
94
77
 
@@ -96,7 +79,7 @@ def run_ansible_in_environment(
96
79
  if locking:
97
80
  lock = Redlock(
98
81
  key=f"lock-ansible-{environment}-{role}",
99
- masters={redis},
82
+ masters={utils.redis},
100
83
  auto_release_time=auto_release_time,
101
84
  )
102
85
 
@@ -178,14 +161,14 @@ def run_ansible_in_environment(
178
161
  while p.poll() is None:
179
162
  line = p.stdout.readline().decode("utf-8")
180
163
  if publish:
181
- redis.xadd(request_id, {"type": "stdout", "content": line})
164
+ utils.redis.xadd(request_id, {"type": "stdout", "content": line})
182
165
  result += line
183
166
 
184
167
  rc = p.wait(timeout=60)
185
168
 
186
169
  if publish:
187
- redis.xadd(request_id, {"type": "rc", "content": rc})
188
- redis.xadd(request_id, {"type": "action", "content": "quit"})
170
+ utils.redis.xadd(request_id, {"type": "rc", "content": rc})
171
+ utils.redis.xadd(request_id, {"type": "action", "content": "quit"})
189
172
 
190
173
  if locking:
191
174
  lock.release()
@@ -209,7 +192,7 @@ def run_command(
209
192
  if locking:
210
193
  lock = Redlock(
211
194
  key=f"lock-{command}",
212
- masters={redis},
195
+ masters={utils.redis},
213
196
  auto_release_time=auto_release_time,
214
197
  )
215
198
 
@@ -222,14 +205,14 @@ def run_command(
222
205
  while p.poll() is None:
223
206
  line = p.stdout.readline().decode("utf-8")
224
207
  if publish:
225
- redis.xadd(request_id, {"type": "stdout", "content": line})
208
+ utils.redis.xadd(request_id, {"type": "stdout", "content": line})
226
209
  result += line
227
210
 
228
211
  rc = p.wait(timeout=60)
229
212
 
230
213
  if publish:
231
- redis.xadd(request_id, {"type": "rc", "content": rc})
232
- redis.xadd(request_id, {"type": "action", "content": "quit"})
214
+ utils.redis.xadd(request_id, {"type": "rc", "content": rc})
215
+ utils.redis.xadd(request_id, {"type": "action", "content": "quit"})
233
216
 
234
217
  if locking:
235
218
  lock.release()
@@ -238,23 +221,12 @@ def run_command(
238
221
 
239
222
 
240
223
  def handle_task(t, wait=True, format="log", timeout=3600):
241
- global redis
242
-
243
- if not redis:
244
- redis = Redis(
245
- host=settings.REDIS_HOST,
246
- port=settings.REDIS_PORT,
247
- db=settings.REDIS_DB,
248
- socket_keepalive=True,
249
- )
250
- redis.ping()
251
-
252
224
  rc = 0
253
225
  if wait:
254
226
  stoptime = time.time() + timeout
255
227
  last_id = 0
256
228
  while time.time() < stoptime:
257
- data = redis.xread(
229
+ data = utils.redis.xread(
258
230
  {str(t.task_id): last_id}, count=1, block=(timeout * 1000)
259
231
  )
260
232
  if data:
@@ -266,7 +238,7 @@ def handle_task(t, wait=True, format="log", timeout=3600):
266
238
  message_content = message[b"content"].decode()
267
239
 
268
240
  logger.debug(f"Processing message {last_id} of type {message_type}")
269
- redis.xdel(str(t.task_id), last_id)
241
+ utils.redis.xdel(str(t.task_id), last_id)
270
242
 
271
243
  if message_type == "stdout":
272
244
  print(message_content, end="", flush=True)
@@ -279,7 +251,7 @@ def handle_task(t, wait=True, format="log", timeout=3600):
279
251
  elif message_type == "rc":
280
252
  rc = int(message_content)
281
253
  elif message_type == "action" and message_content == "quit":
282
- redis.close()
254
+ utils.redis.close()
283
255
  return rc
284
256
  else:
285
257
  logger.info(
osism/tasks/conductor.py CHANGED
@@ -5,10 +5,8 @@ from celery.signals import worker_process_init
5
5
  import keystoneauth1
6
6
  from loguru import logger
7
7
  import openstack
8
- from redis import Redis
9
8
  import yaml
10
9
 
11
- from osism import settings
12
10
  from osism.tasks import Config
13
11
 
14
12
  app = Celery("conductor")
@@ -16,21 +14,11 @@ app.config_from_object(Config)
16
14
 
17
15
 
18
16
  configuration = {}
19
- redis = None
20
17
 
21
18
 
22
19
  @worker_process_init.connect
23
20
  def celery_init_worker(**kwargs):
24
21
  global configuration
25
- global redis
26
-
27
- redis = Redis(
28
- host=settings.REDIS_HOST,
29
- port=settings.REDIS_PORT,
30
- db=settings.REDIS_DB,
31
- socket_keepalive=True,
32
- )
33
- redis.ping()
34
22
 
35
23
  # Parameters come from the environment, OS_*
36
24
  try:
osism/tasks/netbox.py CHANGED
@@ -4,34 +4,19 @@ from celery import Celery
4
4
  from celery.signals import worker_process_init
5
5
  import json
6
6
  import pynetbox
7
- from redis import Redis
8
7
 
9
- from osism import settings
8
+ from osism import settings, utils
10
9
  from osism.actions import manage_device, manage_interface
11
10
  from osism.tasks import Config, openstack, run_command
12
11
 
13
12
  app = Celery("netbox")
14
13
  app.config_from_object(Config)
15
14
 
16
- redis = None
17
- nb = None
18
-
19
15
 
20
16
  @worker_process_init.connect
21
17
  def celery_init_worker(**kwargs):
22
- global nb
23
- global redis
24
-
25
- redis = Redis(
26
- host=settings.REDIS_HOST,
27
- port=settings.REDIS_PORT,
28
- db=settings.REDIS_DB,
29
- socket_keepalive=True,
30
- )
31
- redis.ping()
32
-
33
18
  if settings.NETBOX_URL and settings.NETBOX_TOKEN:
34
- nb = pynetbox.api(settings.NETBOX_URL, token=settings.NETBOX_TOKEN)
19
+ utils.nb = pynetbox.api(settings.NETBOX_URL, token=settings.NETBOX_TOKEN)
35
20
 
36
21
  if settings.IGNORE_SSL_ERRORS:
37
22
  import requests
@@ -39,7 +24,7 @@ def celery_init_worker(**kwargs):
39
24
  requests.packages.urllib3.disable_warnings()
40
25
  session = requests.Session()
41
26
  session.verify = False
42
- nb.http_session = session
27
+ utils.nb.http_session = session
43
28
 
44
29
 
45
30
  @app.on_after_configure.connect
@@ -99,9 +84,7 @@ def set_maintenance(self, device=None, state=None):
99
84
  def get_devices_not_yet_registered_in_ironic(
100
85
  self, status="active", tags=["managed-by-ironic"], ironic_enabled=True
101
86
  ):
102
- global nb
103
-
104
- devices = nb.dcim.devices.filter(
87
+ devices = utils.nb.dcim.devices.filter(
105
88
  tag=tags, status=status, cf_ironic_enabled=[ironic_enabled]
106
89
  )
107
90
 
@@ -122,9 +105,7 @@ def get_devices_not_yet_registered_in_ironic(
122
105
  name="osism.tasks.netbox.get_devices_that_should_have_an_allocation_in_ironic",
123
106
  )
124
107
  def get_devices_that_should_have_an_allocation_in_ironic(self):
125
- global nb
126
-
127
- devices = nb.dcim.devices.filter(
108
+ devices = utils.nb.dcim.devices.filter(
128
109
  tag=["managed-by-ironic", "managed-by-osism"],
129
110
  status="active",
130
111
  cf_ironic_enabled=[True],
@@ -164,8 +145,6 @@ def manage(self, *arguments, publish=True, locking=False, auto_release_time=3600
164
145
 
165
146
  @app.task(bind=True, name="osism.tasks.netbox.ping")
166
147
  def ping(self):
167
- global nb
168
-
169
- status = nb.status()
148
+ status = utils.nb.status()
170
149
 
171
150
  return status
osism/tasks/openstack.py CHANGED
@@ -4,44 +4,17 @@ import copy
4
4
  import ipaddress
5
5
 
6
6
  from celery import Celery
7
- from celery.signals import worker_process_init
8
7
  import jinja2
9
- import keystoneauth1
10
- import openstack
8
+ from openstack.exceptions import ConflictException, ResourceNotFound, ResourceFailure
11
9
  from pottery import Redlock
12
- from redis import Redis
13
10
  import tempfile
14
11
 
15
- from osism import settings
16
- from osism.tasks import Config, conductor, netbox, run_command
17
12
  from osism import utils
13
+ from osism.tasks import Config, conductor, netbox, run_command
18
14
 
19
15
  app = Celery("openstack")
20
16
  app.config_from_object(Config)
21
17
 
22
- redis = None
23
- conn = None
24
-
25
-
26
- @worker_process_init.connect
27
- def celery_init_worker(**kwargs):
28
- global conn
29
- global redis
30
-
31
- redis = Redis(
32
- host=settings.REDIS_HOST,
33
- port=settings.REDIS_PORT,
34
- db=settings.REDIS_DB,
35
- socket_keepalive=True,
36
- )
37
- redis.ping()
38
-
39
- # Parameters come from the environment, OS_*
40
- try:
41
- conn = openstack.connect()
42
- except keystoneauth1.exceptions.auth_plugins.MissingRequiredOptions:
43
- pass
44
-
45
18
 
46
19
  @app.on_after_configure.connect
47
20
  def setup_periodic_tasks(sender, **kwargs):
@@ -50,24 +23,28 @@ def setup_periodic_tasks(sender, **kwargs):
50
23
 
51
24
  @app.task(bind=True, name="osism.tasks.openstack.image_get")
52
25
  def image_get(self, image_name):
26
+ conn = utils.get_openstack_connection()
53
27
  result = conn.image.find_image(image_name)
54
28
  return result.id
55
29
 
56
30
 
57
31
  @app.task(bind=True, name="osism.tasks.openstack.network_get")
58
32
  def network_get(self, network_name):
33
+ conn = utils.get_openstack_connection()
59
34
  result = conn.network.find_network(network_name)
60
35
  return result.id
61
36
 
62
37
 
63
38
  @app.task(bind=True, name="osism.tasks.openstack.baremetal_node_show")
64
39
  def baremetal_node_show(self, node_id_or_name):
40
+ conn = utils.get_openstack_connection()
65
41
  result = conn.baremetal.find_node(node_id_or_name)
66
42
  return result
67
43
 
68
44
 
69
45
  @app.task(bind=True, name="osism.tasks.openstack.baremetal_node_list")
70
46
  def baremetal_node_list(self):
47
+ conn = utils.get_openstack_connection()
71
48
  nodes = conn.baremetal.nodes()
72
49
  result = []
73
50
 
@@ -102,7 +79,7 @@ def baremetal_introspection_status(self, node_id_or_name):
102
79
 
103
80
  @app.task(bind=True, name="osism.tasks.openstack.baremetal_get_network_interface_name")
104
81
  def baremetal_get_network_interface_name(self, node_name, mac_address):
105
- global conn
82
+ conn = utils.get_openstack_connection()
106
83
 
107
84
  introspection = conn.baremetal_introspection.get_introspection(node_name)
108
85
 
@@ -124,18 +101,18 @@ def baremetal_get_network_interface_name(self, node_name, mac_address):
124
101
 
125
102
  @app.task(bind=True, name="osism.tasks.openstack.baremetal_set_node_provision_state")
126
103
  def baremetal_set_node_provision_state(self, node, state):
127
- global conn
104
+ conn = utils.get_openstack_connection()
128
105
  conn.baremetal.set_node_provision_state(node, state)
129
106
 
130
107
 
131
108
  @app.task(bind=True, name="osism.tasks.openstack.baremetal_create_allocations")
132
109
  def baremetal_create_allocations(self, nodes):
133
- global conn
110
+ conn = utils.get_openstack_connection()
134
111
 
135
112
  for node in nodes:
136
113
  try:
137
114
  allocation_a = conn.baremetal.get_allocation(allocation=node)
138
- except openstack.exceptions.ResourceNotFound:
115
+ except ResourceNotFound:
139
116
  allocation_a = None
140
117
 
141
118
  if not allocation_a:
@@ -154,7 +131,7 @@ def baremetal_create_allocations(self, nodes):
154
131
 
155
132
  @app.task(bind=True, name="osism.tasks.openstack.baremetal_create_nodes")
156
133
  def baremetal_create_nodes(self, nodes, ironic_parameters):
157
- global conn
134
+ conn = utils.get_openstack_connection()
158
135
 
159
136
  for node in nodes:
160
137
  # TODO: Filter on mgmt_only
@@ -208,10 +185,10 @@ def baremetal_create_nodes(self, nodes, ironic_parameters):
208
185
  }
209
186
  device_a.save()
210
187
 
211
- except openstack.exceptions.ResourceFailure:
188
+ except ResourceFailure:
212
189
  # TODO: Do something useful here
213
190
  pass
214
- except openstack.exceptions.ConflictException:
191
+ except ConflictException:
215
192
  # The node already exists and has a wronge state in the Netbox
216
193
  device_a = utils.nb.dcim.devices.get(name=node)
217
194
  device_a.custom_fields = {
@@ -224,7 +201,7 @@ def baremetal_create_nodes(self, nodes, ironic_parameters):
224
201
  def baremetal_check_allocations(self):
225
202
  lock = Redlock(
226
203
  key="lock_osism_tasks_openstack_baremetal_check_allocations",
227
- masters={redis},
204
+ masters={utils.redis},
228
205
  auto_release_time=60,
229
206
  )
230
207
 
@@ -237,6 +214,8 @@ def baremetal_check_allocations(self):
237
214
 
238
215
  @app.task(bind=True, name="osism.tasks.openstack.baremetal_create_internal_flavor")
239
216
  def baremetal_create_internal_flavor(self, node):
217
+ conn = utils.get_openstack_connection()
218
+
240
219
  flavor_a = conn.compute.create_flavor(
241
220
  name=f"osism-{node}", ram=1, vcpus=1, disk=1, is_public=False
242
221
  )
@@ -252,6 +231,8 @@ def baremetal_create_internal_flavor(self, node):
252
231
 
253
232
  @app.task(bind=True, name="osism.tasks.openstack.baremetal_delete_internal_flavor")
254
233
  def baremetal_delete_internal_flavor(self, node):
234
+ conn = utils.get_openstack_connection()
235
+
255
236
  flavor = conn.compute.get_flavor(f"osism-{node}")
256
237
  conn.compute.delete_flavor(flavor)
257
238
 
osism/tasks/reconciler.py CHANGED
@@ -4,31 +4,14 @@ import io
4
4
  import subprocess
5
5
 
6
6
  from celery import Celery
7
- from celery.signals import worker_process_init
8
7
  from loguru import logger
9
8
  from pottery import Redlock
10
- from redis import Redis
11
- from osism import settings
9
+ from osism import settings, utils
12
10
  from osism.tasks import Config
13
11
 
14
12
  app = Celery("reconciler")
15
13
  app.config_from_object(Config)
16
14
 
17
- redis = None
18
-
19
-
20
- @worker_process_init.connect
21
- def celery_init_worker(**kwargs):
22
- global redis
23
-
24
- redis = Redis(
25
- host=settings.REDIS_HOST,
26
- port=settings.REDIS_PORT,
27
- db=settings.REDIS_DB,
28
- socket_keepalive=True,
29
- )
30
- redis.ping()
31
-
32
15
 
33
16
  @app.on_after_configure.connect
34
17
  def setup_periodic_tasks(sender, **kwargs):
@@ -40,7 +23,9 @@ def setup_periodic_tasks(sender, **kwargs):
40
23
  @app.task(bind=True, name="osism.tasks.reconciler.run")
41
24
  def run(self, publish=True):
42
25
  lock = Redlock(
43
- key="lock_osism_tasks_reconciler_run", masters={redis}, auto_release_time=60
26
+ key="lock_osism_tasks_reconciler_run",
27
+ masters={utils.redis},
28
+ auto_release_time=60,
44
29
  )
45
30
 
46
31
  if lock.acquire(timeout=20):
@@ -51,13 +36,13 @@ def run(self, publish=True):
51
36
 
52
37
  for line in io.TextIOWrapper(p.stdout, encoding="utf-8"):
53
38
  if publish:
54
- redis.xadd(self.request.id, {"type": "stdout", "content": line})
39
+ utils.redis.xadd(self.request.id, {"type": "stdout", "content": line})
55
40
 
56
41
  rc = p.wait(timeout=60)
57
42
 
58
43
  if publish:
59
- redis.xadd(self.request.id, {"type": "rc", "content": rc})
60
- redis.xadd(self.request.id, {"type": "action", "content": "quit"})
44
+ utils.redis.xadd(self.request.id, {"type": "rc", "content": rc})
45
+ utils.redis.xadd(self.request.id, {"type": "action", "content": "quit"})
61
46
 
62
47
  lock.release()
63
48
 
@@ -66,7 +51,7 @@ def run(self, publish=True):
66
51
  def run_on_change(self):
67
52
  lock = Redlock(
68
53
  key="lock_osism_tasks_reconciler_run_on_change",
69
- masters={redis},
54
+ masters={utils.redis},
70
55
  auto_release_time=60,
71
56
  )
72
57
 
@@ -84,7 +69,7 @@ def run_on_change(self):
84
69
  def sync_inventory_with_netbox(self):
85
70
  lock = Redlock(
86
71
  key="lock_osism_tasks_reconciler_sync_inventory_with_netbox",
87
- masters={redis},
72
+ masters={utils.redis},
88
73
  auto_release_time=60,
89
74
  )
90
75
 
@@ -98,13 +83,13 @@ def sync_inventory_with_netbox(self):
98
83
 
99
84
  for line in io.TextIOWrapper(p.stdout, encoding="utf-8"):
100
85
  # NOTE: use task_id or request_id in future
101
- redis.publish(
86
+ utils.redis.publish(
102
87
  "netbox-sync-inventory-with-netbox", {"type": "stdout", "content": line}
103
88
  )
104
89
 
105
90
  lock.release()
106
91
 
107
92
  # NOTE: use task_id or request_id in future
108
- redis.publish(
93
+ utils.redis.publish(
109
94
  "netbox-sync-inventory-with-netbox", {"type": "action", "content": "quit"}
110
95
  )
osism/utils/__init__.py CHANGED
@@ -1,5 +1,7 @@
1
1
  # SPDX-License-Identifier: Apache-2.0
2
2
 
3
+ import keystoneauth1
4
+ import openstack
3
5
  import pynetbox
4
6
  from redis import Redis
5
7
  import urllib3
@@ -29,6 +31,15 @@ else:
29
31
  nb = None
30
32
 
31
33
 
34
+ def get_openstack_connection():
35
+ try:
36
+ conn = openstack.connect()
37
+ except keystoneauth1.exceptions.auth_plugins.MissingRequiredOptions:
38
+ pass
39
+
40
+ return conn
41
+
42
+
32
43
  # https://stackoverflow.com/questions/2361426/get-the-first-item-from-an-iterable-that-matches-a-condition
33
44
  def first(iterable, condition=lambda x: True):
34
45
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: osism
3
- Version: 0.20250326.0
3
+ Version: 0.20250331.0
4
4
  Summary: OSISM manager interface
5
5
  Home-page: https://github.com/osism/python-osism
6
6
  Author: OSISM GmbH
@@ -37,7 +37,7 @@ Requires-Dist: flower==2.0.1
37
37
  Requires-Dist: hiredis==3.1.0
38
38
  Requires-Dist: jc==1.25.4
39
39
  Requires-Dist: keystoneauth1==5.10.0
40
- Requires-Dist: kombu==5.5.1
40
+ Requires-Dist: kombu==5.5.2
41
41
  Requires-Dist: kubernetes==32.0.1
42
42
  Requires-Dist: loguru==0.7.3
43
43
  Requires-Dist: netmiko==4.5.0
@@ -48,7 +48,7 @@ Requires-Dist: pottery==3.0.1
48
48
  Requires-Dist: prompt-toolkit==3.0.50
49
49
  Requires-Dist: pydantic==1.10.21
50
50
  Requires-Dist: pynetbox==7.4.1
51
- Requires-Dist: pytest-testinfra==10.1.1
51
+ Requires-Dist: pytest-testinfra==10.2.2
52
52
  Requires-Dist: python-dateutil==2.9.0.post0
53
53
  Requires-Dist: setuptools==78.1.0
54
54
  Requires-Dist: sqlmodel==0.0.24
@@ -1,6 +1,6 @@
1
1
  osism/__init__.py,sha256=1UiNTBus0V0f2AbZQzAtVtu6zkfCCrw0OTq--NwFAqY,341
2
2
  osism/__main__.py,sha256=ILe4gu61xEISiBsxanqTQIdSkV-YhpZXTRlguCYyssk,141
3
- osism/api.py,sha256=X3IVLWbKMtfozJ5sEx6sLEZ1rD4U9s3uNnLLwxiwDjs,4802
3
+ osism/api.py,sha256=Lvkdd92tvv9RtoMs9RtvqsN3DiSKPdSll24J3wRzbBY,4793
4
4
  osism/main.py,sha256=Dt2-9sLXcS-Ny4DAz7hrha-KRc7zd7BFUTRdfs_X8z4,893
5
5
  osism/settings.py,sha256=m__DltxKQo5D-vDKKwY8RNBVs5bverYdJmtyVyln_6o,1049
6
6
  osism/actions/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
@@ -16,7 +16,7 @@ osism/commands/container.py,sha256=Fku2GaCM3Idq_FxExUtNqjrEM0XYjpVvXmueSVO8S_c,1
16
16
  osism/commands/get.py,sha256=ryytjtXWmlMV0NucP5tGkMZu0nIlC4xVtjRk4iMZ06c,8967
17
17
  osism/commands/log.py,sha256=2IpYuosC7FZwwLvM8HmKSU1NRNIelVVYzqjjVMCrOJk,4072
18
18
  osism/commands/manage.py,sha256=SDJyH3zwdaOjVWURIIjm8WMo6zSor1Y_TiTYgeMt4pI,11932
19
- osism/commands/netbox.py,sha256=DMAgP9o9AUjw1Cf3MLjSQ36vr5NckGKIsAPNQictboc,4702
19
+ osism/commands/netbox.py,sha256=FYBHcOR_cO-n7rcf4V_-DbwUCgMLFmrrPKCjd0zQOp4,4548
20
20
  osism/commands/noset.py,sha256=7zDFuFMyNpo7DUOKcNiYV8nodtdMOYFp5LDPcuJhlZ8,1481
21
21
  osism/commands/reconciler.py,sha256=Ja_b86gX6-_Pr3DmrUUvskmEnnJpHQ-XJNQLycMJeyc,2818
22
22
  osism/commands/server.py,sha256=zFXRdYoj4ZNDJNPSaGddMPEWxt8G2GyMomPOcCOaN3c,4137
@@ -28,30 +28,30 @@ osism/commands/task.py,sha256=mwJJ7a71Lw3o_FX7j3rR0-NbPdPwMDOjbOAiiXE4uGc,543
28
28
  osism/commands/validate.py,sha256=hIQB0zk4xIBZJORtBp_tWrXTRKKhB2qi6j-mznDxKR4,4191
29
29
  osism/commands/vault.py,sha256=Ip0IMR7zaBkPbLJenXr4ZwxM6FnozZ9wn9rwHmFHo8s,1818
30
30
  osism/commands/volume.py,sha256=SqD9pYgtcYnMu6sB2pG8lfrLHRq6GzOb_-RkWOOVZPo,3156
31
- osism/commands/wait.py,sha256=LFs0xuA4VXTfVw_BXiZB2rPfb33B8orFdpxJdtwMTKA,6857
31
+ osism/commands/wait.py,sha256=mKFDqEXcaLlKw1T3MuBEZpNh7CeL3lpUXgubD2_f8es,6580
32
32
  osism/commands/worker.py,sha256=iraCOEhCp7WgfjfZ0-12XQYQPUjpi9rSJK5Z9JfNJk4,1651
33
33
  osism/core/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
34
- osism/core/enums.py,sha256=kfETfN2_gH6Rv_dYoqX1AafI_3F-y87N3Gajsyd0EQo,9568
34
+ osism/core/enums.py,sha256=UDV3WoOp9kfGTPCQ94tr-2v6c07pNP2kYrxxv6pwxDI,9638
35
35
  osism/core/playbooks.py,sha256=M3T3ajV-8Lt-orsRO3jAoukhaoYFr4EZ2dzYXQjt1kg,728
36
36
  osism/data/__init__.py,sha256=izXdh0J3vPLQI7kBhJI7ibJQzPqU_nlONP0L4Cf_k6A,1504
37
37
  osism/plugins/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
38
38
  osism/services/__init__.py,sha256=bG7Ffen4LvQtgnYPFEpFccsWs81t4zqqeqn9ZeirH6E,38
39
39
  osism/services/listener.py,sha256=JjCdwPG5U9b_xYDpGFQeiLPP4y00GM3Me6NW1tt6Jws,11275
40
- osism/tasks/__init__.py,sha256=qZQGMeaaeUN9CUBqVXGEx2pvDZpDJbhudq0jl4-7GRU,9111
40
+ osism/tasks/__init__.py,sha256=lrSkcZtbzhWsLS4hWadKfpP_tCd1pX1IhvrBU3EhKmM,8605
41
41
  osism/tasks/ansible.py,sha256=RcLxLrjzL5_X6OjNHm3H0lZlmKKlYKIANB0M4_d4chE,1109
42
42
  osism/tasks/ceph.py,sha256=eIQkah3Kj4INtOkF9kTjHbXJ3_J2lg48EWJKfHc-UYw,615
43
- osism/tasks/conductor.py,sha256=g9ulqWlGim0DjwQkVgW8Tl8MsXBGuukuQvM12CXbEmM,3892
43
+ osism/tasks/conductor.py,sha256=P52Avy8OgNQ4koZp3QZLXJiN9uIiBcqrmDpc3UXsPzs,3639
44
44
  osism/tasks/kolla.py,sha256=wJQpWn_01iWLkr7l7T7RNrQGfRgsgmYi4WQlTmNGvew,618
45
45
  osism/tasks/kubernetes.py,sha256=VzXq_VrYU_CLm4cOruqnE3Kq2ydfO9glZ3p0bp3OYoc,625
46
- osism/tasks/netbox.py,sha256=yR8z6VYkNXmNCsHzxP6KGmPtGW5mbpLks8XEw6TUwjk,4692
47
- osism/tasks/openstack.py,sha256=RkP1K-UhD3yJea1YD9cPyc5IWEvS-E8L6CCAiJlEpf8,10463
48
- osism/tasks/reconciler.py,sha256=q_J825nw8haIcYS-FME5oWlaiSPmDbAGeB6NK6Vj00w,2974
49
- osism/utils/__init__.py,sha256=5yng8l5Jd6GhNO4FNi6iYH4569UuTYAynamANgZnm1E,1258
50
- osism-0.20250326.0.dist-info/licenses/AUTHORS,sha256=EKFIR9F27AvoEXp1cA6FkGbjEOFt4Rcbipr5RJc7jSs,64
51
- osism-0.20250326.0.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
52
- osism-0.20250326.0.dist-info/METADATA,sha256=7k0X9KTHpjfEgTKYV-Rw3biNu57oWLwLlEXT5EtG2vE,2972
53
- osism-0.20250326.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
54
- osism-0.20250326.0.dist-info/entry_points.txt,sha256=DlfrvU14rI55WuTrwNRoce9FY3ric4HeZKZx_Z3NzCw,3015
55
- osism-0.20250326.0.dist-info/pbr.json,sha256=i-cyCN-68l6O9MTObxxZqkRCTq2ElZumvNW_esL1WmI,47
56
- osism-0.20250326.0.dist-info/top_level.txt,sha256=8L8dsI9hcaGHsdnR4k_LN9EM78EhwrXRFHyAryPXZtY,6
57
- osism-0.20250326.0.dist-info/RECORD,,
46
+ osism/tasks/netbox.py,sha256=JTgMLp5WAGoupU5Os6xWnKHXACxfXVS33wM1rvbz6Y0,4432
47
+ osism/tasks/openstack.py,sha256=nhHiEcmI_AjM-oYnqjlJ0-c9qYZRQeruOTJsLbScxKI,10258
48
+ osism/tasks/reconciler.py,sha256=RGUcax2gDuyVLw1nGRQn5izXclnPBo9MRl0ndLDiiYQ,2707
49
+ osism/utils/__init__.py,sha256=DP2D7xyXnfWuH-c26elIwdwrMSY-oSkVsLFKsQfna9w,1477
50
+ osism-0.20250331.0.dist-info/licenses/AUTHORS,sha256=EKFIR9F27AvoEXp1cA6FkGbjEOFt4Rcbipr5RJc7jSs,64
51
+ osism-0.20250331.0.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
52
+ osism-0.20250331.0.dist-info/METADATA,sha256=0iUarhckKfE774zkRlFp8Pn21wK2bW30nztf0udL2t8,2972
53
+ osism-0.20250331.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
54
+ osism-0.20250331.0.dist-info/entry_points.txt,sha256=DlfrvU14rI55WuTrwNRoce9FY3ric4HeZKZx_Z3NzCw,3015
55
+ osism-0.20250331.0.dist-info/pbr.json,sha256=dAx-E5EYMfbySf6Y9YoFJwWMs-TE1eIlvi2JwTL12Nw,47
56
+ osism-0.20250331.0.dist-info/top_level.txt,sha256=8L8dsI9hcaGHsdnR4k_LN9EM78EhwrXRFHyAryPXZtY,6
57
+ osism-0.20250331.0.dist-info/RECORD,,
@@ -0,0 +1 @@
1
+ {"git_version": "8324e98", "is_release": false}
@@ -1 +0,0 @@
1
- {"git_version": "908ac32", "is_release": false}