diracx-cli 0.0.1a25__tar.gz → 0.0.1a27__tar.gz
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.
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/PKG-INFO +1 -1
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx/cli/auth.py +2 -1
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx/cli/internal/legacy.py +114 -35
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx_cli.egg-info/PKG-INFO +1 -1
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/tests/legacy/cs_sync/test_cssync.py +2 -2
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/README.md +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/pyproject.toml +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/setup.cfg +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx/cli/__init__.py +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx/cli/__main__.py +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx/cli/config.py +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx/cli/internal/__init__.py +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx/cli/internal/config.py +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx/cli/jobs.py +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx/cli/py.typed +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx/cli/utils.py +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx_cli.egg-info/SOURCES.txt +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx_cli.egg-info/dependency_links.txt +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx_cli.egg-info/entry_points.txt +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx_cli.egg-info/requires.txt +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/src/diracx_cli.egg-info/top_level.txt +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/tests/legacy/cs_sync/integration_test.cfg +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/tests/legacy/cs_sync/integration_test.yaml +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/tests/legacy/cs_sync/integration_test_buggy.cfg +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/tests/legacy/cs_sync/integration_test_secret.cfg +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/tests/legacy/test_legacy.py +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/tests/test_internal.py +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/tests/test_jobs.py +0 -0
- {diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/tests/test_login.py +0 -0
|
@@ -5,6 +5,7 @@ __all__ = ("app",)
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import json
|
|
7
7
|
import os
|
|
8
|
+
from asyncio import sleep
|
|
8
9
|
from datetime import datetime, timedelta, timezone
|
|
9
10
|
from typing import Annotated, Optional
|
|
10
11
|
|
|
@@ -92,7 +93,7 @@ async def login(
|
|
|
92
93
|
if response.error == "authorization_pending":
|
|
93
94
|
# TODO: Setting more than 5 seconds results in an error
|
|
94
95
|
# Related to keep-alive disconnects from uvicon (--timeout-keep-alive)
|
|
95
|
-
await
|
|
96
|
+
await sleep(2)
|
|
96
97
|
continue
|
|
97
98
|
raise RuntimeError(f"Device flow failed with {response}")
|
|
98
99
|
break
|
|
@@ -4,6 +4,7 @@ import base64
|
|
|
4
4
|
import hashlib
|
|
5
5
|
import json
|
|
6
6
|
import os
|
|
7
|
+
import re
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
from typing import TYPE_CHECKING, cast
|
|
9
10
|
from urllib.parse import urljoin, urlparse
|
|
@@ -26,6 +27,12 @@ from ..utils import AsyncTyper
|
|
|
26
27
|
app = AsyncTyper()
|
|
27
28
|
|
|
28
29
|
|
|
30
|
+
BASE_64_URL_SAFE_PATTERN = (
|
|
31
|
+
r"(?:[A-Za-z0-9\-_]{4})*(?:[A-Za-z0-9\-_]{2}==|[A-Za-z0-9\-_]{3}=)?"
|
|
32
|
+
)
|
|
33
|
+
LEGACY_EXCHANGE_PATTERN = rf"diracx:legacy:({BASE_64_URL_SAFE_PATTERN})"
|
|
34
|
+
|
|
35
|
+
|
|
29
36
|
class IdPConfig(BaseModel):
|
|
30
37
|
URL: str
|
|
31
38
|
ClientID: str
|
|
@@ -182,12 +189,13 @@ def generate_helm_values(
|
|
|
182
189
|
"developer": {"enabled": False},
|
|
183
190
|
"initCs": {"enabled": True},
|
|
184
191
|
"initSecrets": {"enabled": True},
|
|
185
|
-
"initSql": {"enabled": False
|
|
192
|
+
"initSql": {"enabled": False},
|
|
186
193
|
"cert-manager": {"enabled": False},
|
|
187
194
|
"cert-manager-issuer": {"enabled": False},
|
|
188
195
|
"minio": {"enabled": False},
|
|
189
196
|
"dex": {"enabled": False},
|
|
190
197
|
"opensearch": {"enabled": False},
|
|
198
|
+
# This is Openshift specific, change it maybe
|
|
191
199
|
"ingress": {
|
|
192
200
|
"enabled": True,
|
|
193
201
|
"className": None,
|
|
@@ -199,12 +207,7 @@ def generate_helm_values(
|
|
|
199
207
|
},
|
|
200
208
|
"rabbitmq": {"enabled": False},
|
|
201
209
|
"mysql": {"enabled": False},
|
|
202
|
-
"
|
|
203
|
-
"manageOSIndices": False,
|
|
204
|
-
"mysqlDatabases": [],
|
|
205
|
-
"osDatabases": [],
|
|
206
|
-
"settings": {},
|
|
207
|
-
},
|
|
210
|
+
"global": {"images": {"services": "FILL ME"}, "storageClassName": "FILL ME"},
|
|
208
211
|
}
|
|
209
212
|
|
|
210
213
|
cfg = diraccfg.CFG().loadFromBuffer(public_cfg.read_text())
|
|
@@ -216,15 +219,13 @@ def generate_helm_values(
|
|
|
216
219
|
|
|
217
220
|
diracx_url = cfg["DiracX"]["URL"]
|
|
218
221
|
diracx_hostname = urlparse(diracx_url).netloc.split(":", 1)[0]
|
|
219
|
-
|
|
220
|
-
diracx_config = {
|
|
221
|
-
"
|
|
222
|
-
"
|
|
223
|
-
"osDatabases": [],
|
|
224
|
-
"settings": {},
|
|
222
|
+
|
|
223
|
+
diracx_config: dict = {
|
|
224
|
+
"sqlDbs": {},
|
|
225
|
+
"osDbs": {},
|
|
225
226
|
}
|
|
226
227
|
|
|
227
|
-
diracx_settings: dict[str, str] = {}
|
|
228
|
+
diracx_settings: dict[str, str] = {"DIRACX_CONFIG_BACKEND_URL": "FILL ME"}
|
|
228
229
|
diracx_config["settings"] = diracx_settings
|
|
229
230
|
helm_values["diracx"] = diracx_config
|
|
230
231
|
diracx_config["hostname"] = diracx_hostname
|
|
@@ -236,47 +237,122 @@ def generate_helm_values(
|
|
|
236
237
|
]
|
|
237
238
|
)
|
|
238
239
|
|
|
240
|
+
### SQL DBs
|
|
241
|
+
|
|
239
242
|
default_db_user = cfg["Systems"].get("Databases", {}).get("User")
|
|
240
243
|
default_db_password = cfg["Systems"].get("Databases", {}).get("Password")
|
|
241
|
-
|
|
242
|
-
|
|
244
|
+
default_db_host = cfg["Systems"].get("Databases", {}).get("Host", "FILL ME")
|
|
245
|
+
default_db_port = cfg["Systems"].get("Databases", {}).get("Port", "FILL ME")
|
|
243
246
|
|
|
244
247
|
all_db_configs = {}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
248
|
+
sql_dbs = {
|
|
249
|
+
"dbs": {},
|
|
250
|
+
"default": {
|
|
251
|
+
"host": f"{default_db_host}:{default_db_port}",
|
|
252
|
+
"password": default_db_password,
|
|
253
|
+
"rootPassword": "FILL ME",
|
|
254
|
+
"rootUser": "FILL ME",
|
|
255
|
+
"user": default_db_user,
|
|
256
|
+
},
|
|
257
|
+
}
|
|
258
|
+
for _system, system_config in cfg["Systems"].items():
|
|
259
|
+
all_db_configs.update(system_config.get("Databases", {}))
|
|
249
260
|
|
|
250
261
|
from diracx.core.extensions import select_from_extension
|
|
251
262
|
|
|
252
263
|
for entry_point in select_from_extension(group="diracx.db.sql"):
|
|
264
|
+
|
|
253
265
|
db_name = entry_point.name
|
|
266
|
+
db_config = all_db_configs.get(db_name, {})
|
|
267
|
+
|
|
268
|
+
sql_dbs["dbs"][db_name] = {}
|
|
254
269
|
# There is a DIRAC AuthDB, but it is not the same
|
|
255
270
|
# as the DiracX one
|
|
256
271
|
if db_name == "AuthDB":
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
db_config = all_db_configs[db_name]
|
|
261
|
-
url_name = f"DIRACX_DB_URL_{entry_point.name.upper()}"
|
|
262
|
-
db_user = db_config.get("User", default_db_user)
|
|
263
|
-
db_password = db_config.get("Password", default_db_password)
|
|
264
|
-
db_host = db_config["Host"]
|
|
265
|
-
db_port = db_config["Port"]
|
|
272
|
+
sql_dbs["dbs"]["AuthDB"] = {"internalName": "DiracXAuthDB"}
|
|
273
|
+
|
|
274
|
+
if "DBName" in db_config:
|
|
266
275
|
indb_name = db_config["DBName"]
|
|
276
|
+
if indb_name != db_name:
|
|
277
|
+
sql_dbs["dbs"]["internalName"] = indb_name
|
|
278
|
+
if "User" in db_config:
|
|
279
|
+
sql_dbs["dbs"][db_name]["user"] = db_config.get("User")
|
|
280
|
+
if "Password" in db_config:
|
|
281
|
+
sql_dbs["dbs"][db_name]["password"] = db_config.get("Password")
|
|
282
|
+
if "Host" in db_config or "Port" in db_config:
|
|
283
|
+
sql_dbs["dbs"][db_name][
|
|
284
|
+
"host"
|
|
285
|
+
] = f"{db_config.get('Host', default_db_host)}:{db_config.get('Port', default_db_port)}"
|
|
286
|
+
if not sql_dbs["dbs"][db_name]:
|
|
287
|
+
sql_dbs["dbs"][db_name] = None
|
|
288
|
+
|
|
289
|
+
diracx_config["sqlDbs"] = sql_dbs
|
|
290
|
+
|
|
291
|
+
#### END SQL DB
|
|
292
|
+
|
|
293
|
+
# #### OS DBs
|
|
294
|
+
|
|
295
|
+
default_os_db_user = cfg["Systems"].get("NoSQLDatabases", {}).get("User")
|
|
296
|
+
default_os_db_password = cfg["Systems"].get("NoSQLDatabases", {}).get("Password")
|
|
297
|
+
default_os_db_host = cfg["Systems"].get("NoSQLDatabases", {}).get("Host", "FILL ME")
|
|
298
|
+
|
|
299
|
+
os_dbs = {
|
|
300
|
+
"dbs": {},
|
|
301
|
+
"default": {
|
|
302
|
+
"host": f"{default_os_db_host}",
|
|
303
|
+
"password": default_os_db_password,
|
|
304
|
+
"rootPassword": "FILL ME",
|
|
305
|
+
"rootUser": "FILL ME",
|
|
306
|
+
"user": default_os_db_user,
|
|
307
|
+
},
|
|
308
|
+
}
|
|
267
309
|
|
|
268
|
-
|
|
269
|
-
|
|
310
|
+
for entry_point in select_from_extension(group="diracx.db.os"):
|
|
311
|
+
db_name = entry_point.name
|
|
312
|
+
db_config = all_db_configs.get(db_name, {})
|
|
313
|
+
|
|
314
|
+
os_dbs["dbs"][db_name] = {}
|
|
315
|
+
# There is a DIRAC AuthDB, but it is not the same
|
|
316
|
+
# as the DiracX one
|
|
317
|
+
|
|
318
|
+
if "DBName" in db_config:
|
|
319
|
+
indb_name = db_config["DBName"]
|
|
320
|
+
if indb_name != db_name:
|
|
321
|
+
os_dbs["dbs"]["internalName"] = indb_name
|
|
322
|
+
if "User" in db_config:
|
|
323
|
+
os_dbs["dbs"][db_name]["user"] = db_config["User"]
|
|
324
|
+
if "Password" in db_config:
|
|
325
|
+
os_dbs["dbs"][db_name]["password"] = db_config["Password"]
|
|
326
|
+
if "Host" in db_config:
|
|
327
|
+
os_dbs["dbs"][db_name]["host"] = db_config["Host"]
|
|
328
|
+
|
|
329
|
+
if not os_dbs["dbs"][db_name]:
|
|
330
|
+
os_dbs["dbs"][db_name] = None
|
|
331
|
+
|
|
332
|
+
diracx_config["osDbs"] = os_dbs
|
|
333
|
+
|
|
334
|
+
#### End OS DBs
|
|
270
335
|
|
|
271
336
|
# Settings for the legacy
|
|
272
337
|
try:
|
|
338
|
+
if match := re.fullmatch(
|
|
339
|
+
LEGACY_EXCHANGE_PATTERN, cfg["DiracX"]["LegacyExchangeApiKey"]
|
|
340
|
+
):
|
|
341
|
+
raw_token = base64.urlsafe_b64decode(match.group(1))
|
|
342
|
+
else:
|
|
343
|
+
raise ValueError(
|
|
344
|
+
"Invalid authorization header",
|
|
345
|
+
)
|
|
346
|
+
|
|
273
347
|
diracx_settings["DIRACX_LEGACY_EXCHANGE_HASHED_API_KEY"] = hashlib.sha256(
|
|
274
|
-
|
|
348
|
+
raw_token
|
|
275
349
|
).hexdigest()
|
|
276
350
|
except KeyError:
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
351
|
+
error_msg = """
|
|
352
|
+
ERROR: you must have '/DiracX/LegacyExchangeApiKey' already set.
|
|
353
|
+
See the `legacy_exchange` function definition for how to generate it in python
|
|
354
|
+
"""
|
|
355
|
+
typer.echo(error_msg, err=True)
|
|
280
356
|
raise typer.Exit(1) from None
|
|
281
357
|
# Sandboxstore settings
|
|
282
358
|
# TODO: Integrate minio for production use (ingress, etc)
|
|
@@ -295,3 +371,6 @@ def generate_helm_values(
|
|
|
295
371
|
diracx_settings["DIRACX_SERVICE_JOBS_ENABLED"] = "true"
|
|
296
372
|
diracx_settings["DIRACX_SANDBOX_STORE_AUTO_CREATE_BUCKET"] = "true"
|
|
297
373
|
output_file.write_text(yaml.safe_dump(helm_values))
|
|
374
|
+
typer.echo(
|
|
375
|
+
"The file is incomplete and needs manual editing (grep for 'FILL ME')", err=True
|
|
376
|
+
)
|
|
@@ -16,7 +16,7 @@ file_path = Path(__file__).parent
|
|
|
16
16
|
def test_cs_sync(tmp_path, monkeypatch):
|
|
17
17
|
monkeypatch.setenv("DIRAC_COMPAT_ENABLE_CS_CONVERSION", "Yes")
|
|
18
18
|
|
|
19
|
-
output_file = tmp_path / "default.
|
|
19
|
+
output_file = tmp_path / "default.yml"
|
|
20
20
|
|
|
21
21
|
result = runner.invoke(
|
|
22
22
|
app,
|
|
@@ -40,7 +40,7 @@ def test_disabled_vos_empty(tmp_path, monkeypatch):
|
|
|
40
40
|
# # DisabledVOs cannot be set if any Legacy clients are enabled
|
|
41
41
|
monkeypatch.setenv("DIRAC_COMPAT_ENABLE_CS_CONVERSION", "Yes")
|
|
42
42
|
|
|
43
|
-
output_file = tmp_path / "default.
|
|
43
|
+
output_file = tmp_path / "default.yml"
|
|
44
44
|
|
|
45
45
|
result = runner.invoke(
|
|
46
46
|
app,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{diracx_cli-0.0.1a25 → diracx_cli-0.0.1a27}/tests/legacy/cs_sync/integration_test_secret.cfg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|