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 +5 -10
- osism/commands/netbox.py +0 -6
- osism/commands/wait.py +5 -12
- osism/core/enums.py +1 -0
- osism/tasks/__init__.py +13 -41
- osism/tasks/conductor.py +0 -12
- osism/tasks/netbox.py +6 -27
- osism/tasks/openstack.py +18 -37
- osism/tasks/reconciler.py +11 -26
- osism/utils/__init__.py +11 -0
- {osism-0.20250326.0.dist-info → osism-0.20250331.0.dist-info}/METADATA +3 -3
- {osism-0.20250326.0.dist-info → osism-0.20250331.0.dist-info}/RECORD +18 -18
- osism-0.20250331.0.dist-info/pbr.json +1 -0
- osism-0.20250326.0.dist-info/pbr.json +0 -1
- {osism-0.20250326.0.dist-info → osism-0.20250331.0.dist-info}/WHEEL +0 -0
- {osism-0.20250326.0.dist-info → osism-0.20250331.0.dist-info}/entry_points.txt +0 -0
- {osism-0.20250326.0.dist-info → osism-0.20250331.0.dist-info}/licenses/AUTHORS +0 -0
- {osism-0.20250326.0.dist-info → osism-0.20250331.0.dist-info}/licenses/LICENSE +0 -0
- {osism-0.20250326.0.dist-info → osism-0.20250331.0.dist-info}/top_level.txt +0 -0
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
|
-
|
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
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
188
|
+
except ResourceFailure:
|
212
189
|
# TODO: Do something useful here
|
213
190
|
pass
|
214
|
-
except
|
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
|
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",
|
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.
|
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.
|
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.
|
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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
47
|
-
osism/tasks/openstack.py,sha256=
|
48
|
-
osism/tasks/reconciler.py,sha256=
|
49
|
-
osism/utils/__init__.py,sha256=
|
50
|
-
osism-0.
|
51
|
-
osism-0.
|
52
|
-
osism-0.
|
53
|
-
osism-0.
|
54
|
-
osism-0.
|
55
|
-
osism-0.
|
56
|
-
osism-0.
|
57
|
-
osism-0.
|
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}
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|