rucio-clients 32.8.6__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.

Potentially problematic release.


This version of rucio-clients might be problematic. Click here for more details.

Files changed (88) hide show
  1. rucio/__init__.py +18 -0
  2. rucio/alembicrevision.py +16 -0
  3. rucio/client/__init__.py +16 -0
  4. rucio/client/accountclient.py +413 -0
  5. rucio/client/accountlimitclient.py +155 -0
  6. rucio/client/baseclient.py +929 -0
  7. rucio/client/client.py +77 -0
  8. rucio/client/configclient.py +113 -0
  9. rucio/client/credentialclient.py +54 -0
  10. rucio/client/didclient.py +691 -0
  11. rucio/client/diracclient.py +48 -0
  12. rucio/client/downloadclient.py +1674 -0
  13. rucio/client/exportclient.py +44 -0
  14. rucio/client/fileclient.py +51 -0
  15. rucio/client/importclient.py +42 -0
  16. rucio/client/lifetimeclient.py +74 -0
  17. rucio/client/lockclient.py +99 -0
  18. rucio/client/metaclient.py +137 -0
  19. rucio/client/pingclient.py +45 -0
  20. rucio/client/replicaclient.py +444 -0
  21. rucio/client/requestclient.py +109 -0
  22. rucio/client/rseclient.py +664 -0
  23. rucio/client/ruleclient.py +287 -0
  24. rucio/client/scopeclient.py +88 -0
  25. rucio/client/subscriptionclient.py +161 -0
  26. rucio/client/touchclient.py +78 -0
  27. rucio/client/uploadclient.py +871 -0
  28. rucio/common/__init__.py +14 -0
  29. rucio/common/cache.py +74 -0
  30. rucio/common/config.py +796 -0
  31. rucio/common/constants.py +92 -0
  32. rucio/common/constraints.py +18 -0
  33. rucio/common/didtype.py +187 -0
  34. rucio/common/exception.py +1092 -0
  35. rucio/common/extra.py +37 -0
  36. rucio/common/logging.py +404 -0
  37. rucio/common/pcache.py +1387 -0
  38. rucio/common/policy.py +84 -0
  39. rucio/common/schema/__init__.py +143 -0
  40. rucio/common/schema/atlas.py +411 -0
  41. rucio/common/schema/belleii.py +406 -0
  42. rucio/common/schema/cms.py +478 -0
  43. rucio/common/schema/domatpc.py +399 -0
  44. rucio/common/schema/escape.py +424 -0
  45. rucio/common/schema/generic.py +431 -0
  46. rucio/common/schema/generic_multi_vo.py +410 -0
  47. rucio/common/schema/icecube.py +404 -0
  48. rucio/common/schema/lsst.py +423 -0
  49. rucio/common/stomp_utils.py +160 -0
  50. rucio/common/stopwatch.py +56 -0
  51. rucio/common/test_rucio_server.py +148 -0
  52. rucio/common/types.py +158 -0
  53. rucio/common/utils.py +1946 -0
  54. rucio/rse/__init__.py +97 -0
  55. rucio/rse/protocols/__init__.py +14 -0
  56. rucio/rse/protocols/cache.py +123 -0
  57. rucio/rse/protocols/dummy.py +112 -0
  58. rucio/rse/protocols/gfal.py +701 -0
  59. rucio/rse/protocols/globus.py +243 -0
  60. rucio/rse/protocols/gsiftp.py +93 -0
  61. rucio/rse/protocols/http_cache.py +83 -0
  62. rucio/rse/protocols/mock.py +124 -0
  63. rucio/rse/protocols/ngarc.py +210 -0
  64. rucio/rse/protocols/posix.py +251 -0
  65. rucio/rse/protocols/protocol.py +530 -0
  66. rucio/rse/protocols/rclone.py +365 -0
  67. rucio/rse/protocols/rfio.py +137 -0
  68. rucio/rse/protocols/srm.py +339 -0
  69. rucio/rse/protocols/ssh.py +414 -0
  70. rucio/rse/protocols/storm.py +207 -0
  71. rucio/rse/protocols/webdav.py +547 -0
  72. rucio/rse/protocols/xrootd.py +295 -0
  73. rucio/rse/rsemanager.py +752 -0
  74. rucio/vcsversion.py +11 -0
  75. rucio/version.py +46 -0
  76. rucio_clients-32.8.6.data/data/etc/rse-accounts.cfg.template +25 -0
  77. rucio_clients-32.8.6.data/data/etc/rucio.cfg.atlas.client.template +42 -0
  78. rucio_clients-32.8.6.data/data/etc/rucio.cfg.template +257 -0
  79. rucio_clients-32.8.6.data/data/requirements.txt +55 -0
  80. rucio_clients-32.8.6.data/data/rucio_client/merge_rucio_configs.py +147 -0
  81. rucio_clients-32.8.6.data/scripts/rucio +2540 -0
  82. rucio_clients-32.8.6.data/scripts/rucio-admin +2434 -0
  83. rucio_clients-32.8.6.dist-info/METADATA +50 -0
  84. rucio_clients-32.8.6.dist-info/RECORD +88 -0
  85. rucio_clients-32.8.6.dist-info/WHEEL +5 -0
  86. rucio_clients-32.8.6.dist-info/licenses/AUTHORS.rst +94 -0
  87. rucio_clients-32.8.6.dist-info/licenses/LICENSE +201 -0
  88. rucio_clients-32.8.6.dist-info/top_level.txt +1 -0
rucio/common/config.py ADDED
@@ -0,0 +1,796 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ """Provides functions to access the local configuration. The configuration locations are provided by get_config_dirs."""
17
+
18
+ import configparser
19
+ import json
20
+ import os
21
+ from collections.abc import Callable
22
+ from typing import TYPE_CHECKING, overload, Optional, TypeVar, Union
23
+
24
+ from rucio.common import exception
25
+ from rucio.common.exception import ConfigNotFound, DatabaseException
26
+
27
+ _T = TypeVar('_T')
28
+ _U = TypeVar('_U')
29
+
30
+ if TYPE_CHECKING:
31
+ from sqlalchemy.orm import Session
32
+
33
+
34
+ def convert_to_any_type(value) -> Union[bool, int, float, str]:
35
+ if value.lower() in ['true', 'yes', 'on']:
36
+ return True
37
+ elif value.lower() in ['false', 'no', 'off']:
38
+ return False
39
+
40
+ for conv in (int, float):
41
+ try:
42
+ return conv(value)
43
+ except:
44
+ pass
45
+
46
+ return value
47
+
48
+
49
+ def _convert_to_boolean(value):
50
+ if isinstance(value, bool):
51
+ return value
52
+ if value.lower() in ['true', 'yes', 'on', '1']:
53
+ return True
54
+ elif value.lower() in ['false', 'no', 'off', '0']:
55
+ return False
56
+ raise ValueError('Not a boolean: %s' % value)
57
+
58
+
59
+ @overload
60
+ def config_get(
61
+ section: str,
62
+ option: str,
63
+ *,
64
+ clean_cached: bool = ...,
65
+ check_config_table: bool = ...,
66
+ session: "Optional[Session]" = ...,
67
+ use_cache: bool = ...,
68
+ expiration_time: int = ...,
69
+ ) -> str:
70
+ ...
71
+
72
+
73
+ @overload
74
+ def config_get(
75
+ section: str,
76
+ option: str,
77
+ *,
78
+ default: _T = ...,
79
+ clean_cached: bool = ...,
80
+ check_config_table: bool = ...,
81
+ session: "Optional[Session]" = ...,
82
+ use_cache: bool = ...,
83
+ expiration_time: int = ...,
84
+ ) -> Union[str, _T]:
85
+ ...
86
+
87
+
88
+ @overload
89
+ def config_get(
90
+ section: str,
91
+ option: str,
92
+ raise_exception: bool,
93
+ default: _T = ...,
94
+ *,
95
+ clean_cached: bool = ...,
96
+ check_config_table: bool = ...,
97
+ session: "Optional[Session]" = ...,
98
+ use_cache: bool = ...,
99
+ expiration_time: int = ...,
100
+ ) -> Union[str, _T]:
101
+ ...
102
+
103
+
104
+ @overload
105
+ def config_get(
106
+ section: str,
107
+ option: str,
108
+ *,
109
+ clean_cached: bool = ...,
110
+ check_config_table: bool = ...,
111
+ session: "Optional[Session]" = ...,
112
+ use_cache: bool = ...,
113
+ expiration_time: int = ...,
114
+ convert_type_fnc: Callable[[str], _T],
115
+ ) -> _T:
116
+ ...
117
+
118
+
119
+ @overload
120
+ def config_get(
121
+ section: str,
122
+ option: str,
123
+ *,
124
+ default: _T = ...,
125
+ clean_cached: bool = ...,
126
+ check_config_table: bool = ...,
127
+ session: "Optional[Session]" = ...,
128
+ use_cache: bool = ...,
129
+ expiration_time: int = ...,
130
+ convert_type_fnc: Callable[[str], _U],
131
+ ) -> Union[_T, _U]:
132
+ ...
133
+
134
+
135
+ @overload
136
+ def config_get(
137
+ section: str,
138
+ option: str,
139
+ raise_exception: bool,
140
+ default: _T = ...,
141
+ *,
142
+ clean_cached: bool = ...,
143
+ check_config_table: bool = ...,
144
+ session: "Optional[Session]" = ...,
145
+ use_cache: bool = ...,
146
+ expiration_time: int = ...,
147
+ convert_type_fnc: Callable[[str], _U],
148
+ ) -> Union[_T, _U]:
149
+ ...
150
+
151
+
152
+ def config_get(
153
+ section: str,
154
+ option: str,
155
+ raise_exception: bool = True,
156
+ default: _U = None,
157
+ clean_cached: bool = False,
158
+ check_config_table: bool = True,
159
+ session: "Optional[Session]" = None,
160
+ use_cache: bool = True,
161
+ expiration_time: int = 900,
162
+ convert_type_fnc: Callable[[str], _T] = lambda x: x,
163
+ ) -> Union[_T, _U]:
164
+ """
165
+ Return the string value for a given option in a section
166
+
167
+ First it looks at the configuration file and, if it is not found, check in the config table only if it is called
168
+ from a server/daemon (and if check_config_table is set).
169
+
170
+ :param section: the named section.
171
+ :param option: the named option.
172
+ :param raise_exception: Boolean to raise or not NoOptionError, NoSectionError or RuntimeError.
173
+ :param default: the default value if not found.
174
+ :param clean_cached: Deletes the cached config singleton instance if no config value is found
175
+ :param check_config_table: if not set, avoid looking at config table even if it is called from server/daemon
176
+ :param session: The database session in use. Only used if not found in config file and if it is called from
177
+ server/daemon
178
+ :param use_cache: Boolean if the cache should be used. Only used if not found in config file and if it is called
179
+ from server/daemon
180
+ :param expiration_time: Time after that the cached value gets ignored. Only used if not found in config file and if
181
+ it is called from server/daemon
182
+ :param convert_type_fnc: A function used to parse the string config value into the desired destination type
183
+
184
+ :returns: the configuration value.
185
+
186
+ :raises NoOptionError
187
+ :raises NoSectionError
188
+ :raises RuntimeError
189
+ """
190
+ try:
191
+ return convert_type_fnc(get_config().get(section, option))
192
+ except (configparser.NoOptionError, configparser.NoSectionError, RuntimeError) as err:
193
+ try:
194
+ legacy_config = get_legacy_config(section, option)
195
+ if legacy_config is not None:
196
+ return convert_type_fnc(legacy_config)
197
+ except RuntimeError:
198
+ pass
199
+
200
+ from rucio.common.utils import is_client
201
+ client_mode = is_client()
202
+
203
+ if not client_mode and check_config_table:
204
+ try:
205
+ return __config_get_table(section=section, option=option, raise_exception=raise_exception,
206
+ default=default, clean_cached=clean_cached, session=session,
207
+ use_cache=use_cache, expiration_time=expiration_time,
208
+ convert_type_fnc=convert_type_fnc)
209
+ except (ConfigNotFound, DatabaseException, ImportError):
210
+ raise err
211
+ else:
212
+ if raise_exception and default is None:
213
+ raise err
214
+ if clean_cached:
215
+ clean_cached_config()
216
+ return default
217
+
218
+
219
+ def get_legacy_config(section: str, option: str):
220
+ """
221
+ Returns a legacy config value, if it is present.
222
+
223
+ :param section: The section of the new config.
224
+ :param option: The option of the new config.
225
+ :returns: The string value of the legacy option if one is found, None otherwise.
226
+ """
227
+ LEGACY_SECTION_NAME = {}
228
+ LEGACY_OPTION_NAME = {}
229
+
230
+ section = LEGACY_SECTION_NAME.get(section, section)
231
+ option = LEGACY_OPTION_NAME.get(option, option)
232
+
233
+ if config_has_option(section, option):
234
+ return get_config().get(section, option)
235
+
236
+ return None
237
+
238
+
239
+ def config_has_section(section: str) -> bool:
240
+ """
241
+ Indicates whether the named section is present in the configuration. The DEFAULT section is not acknowledged.
242
+
243
+ :param section: Name of section in the Rucio config to verify.
244
+ :returns: True if the section exists in the configuration; False otherwise
245
+ """
246
+ return get_config().has_section(section)
247
+
248
+
249
+ def config_has_option(section: str, option: str) -> bool:
250
+ """
251
+ Indicates whether the named option is present in the configuration. The DEFAULT section is not acknowledged.
252
+
253
+ :param section: Name of section in the Rucio config to verify.
254
+ :param option: Name of option in the Rucio config to verify.
255
+ :returns: True if the section and option exists in the configuration; False otherwise
256
+ """
257
+ return get_config().has_option(section, option)
258
+
259
+
260
+ def config_add_section(section: str):
261
+ """
262
+ Add a new section to the configuration object. Throws DuplicateSectionError if it already exists.
263
+
264
+ :param section: Name of section in the Rucio config to add.
265
+ :returns: None
266
+ """
267
+ return get_config().add_section(section)
268
+
269
+
270
+ @overload
271
+ def config_get_int(
272
+ section: str,
273
+ option: str,
274
+ *,
275
+ check_config_table: bool = ...,
276
+ session: "Optional[Session]" = ...,
277
+ use_cache: bool = ...,
278
+ expiration_time: int = ...,
279
+ ) -> int:
280
+ ...
281
+
282
+
283
+ @overload
284
+ def config_get_int(
285
+ section: str,
286
+ option: str,
287
+ *,
288
+ default: int = ...,
289
+ check_config_table: bool = ...,
290
+ session: "Optional[Session]" = ...,
291
+ use_cache: bool = ...,
292
+ expiration_time: int = ...,
293
+ ) -> int:
294
+ ...
295
+
296
+
297
+ @overload
298
+ def config_get_int(
299
+ section: str,
300
+ option: str,
301
+ raise_exception,
302
+ default: _T = ...,
303
+ *,
304
+ check_config_table: bool = ...,
305
+ session: "Optional[Session]" = ...,
306
+ use_cache: bool = ...,
307
+ expiration_time: int = ...,
308
+ ) -> Union[int, _T]:
309
+ ...
310
+
311
+
312
+ def config_get_int(
313
+ section,
314
+ option,
315
+ raise_exception=True,
316
+ default=None,
317
+ check_config_table=True,
318
+ session=None,
319
+ use_cache=True,
320
+ expiration_time=900,
321
+ ):
322
+ """
323
+ Return the integer value for a given option in a section
324
+
325
+ :param section: the named section.
326
+ :param option: the named option.
327
+ :param raise_exception: Boolean to raise or not NoOptionError, NoSectionError or RuntimeError.
328
+ :param default: the default value if not found.
329
+ :param check_config_table: if not set, avoid looking at config table even if it is called from server/daemon
330
+ :param session: The database session in use. Only used if not found in config file and if it is called from
331
+ server/daemon
332
+ :param use_cache: Boolean if the cache should be used. Only used if not found in config file and if it is called
333
+ from server/daemon
334
+ :param expiration_time: Time after that the cached value gets ignored. Only used if not found in config file and if
335
+ it is called from server/daemon
336
+ :returns: the configuration value.
337
+
338
+ :raises NoOptionError
339
+ :raises NoSectionError
340
+ :raises RuntimeError
341
+ :raises ValueError
342
+ """
343
+ return config_get(
344
+ section,
345
+ option,
346
+ raise_exception=raise_exception,
347
+ default=default,
348
+ check_config_table=check_config_table,
349
+ session=session,
350
+ use_cache=use_cache,
351
+ expiration_time=expiration_time,
352
+ convert_type_fnc=int,
353
+ )
354
+
355
+
356
+ @overload
357
+ def config_get_float(
358
+ section: str,
359
+ option: str,
360
+ *,
361
+ check_config_table: bool = ...,
362
+ session: "Optional[Session]" = ...,
363
+ use_cache: bool = ...,
364
+ expiration_time: int = ...,
365
+ ) -> float:
366
+ ...
367
+
368
+
369
+ @overload
370
+ def config_get_float(
371
+ section: str,
372
+ option: str,
373
+ *,
374
+ default: float = ...,
375
+ check_config_table: bool = ...,
376
+ session: "Optional[Session]" = ...,
377
+ use_cache: bool = ...,
378
+ expiration_time: int = ...,
379
+ ) -> float:
380
+ ...
381
+
382
+
383
+ @overload
384
+ def config_get_float(
385
+ section: str,
386
+ option: str,
387
+ raise_exception,
388
+ default: _T = ...,
389
+ *,
390
+ check_config_table: bool = ...,
391
+ session: "Optional[Session]" = ...,
392
+ use_cache: bool = ...,
393
+ expiration_time: int = ...,
394
+ ) -> Union[float, _T]:
395
+ ...
396
+
397
+
398
+ def config_get_float(
399
+ section,
400
+ option,
401
+ raise_exception=True,
402
+ default=None,
403
+ check_config_table=True,
404
+ session=None,
405
+ use_cache=True,
406
+ expiration_time=900,
407
+ ):
408
+ """
409
+ Return the floating point value for a given option in a section
410
+
411
+ :param section: the named section.
412
+ :param option: the named option.
413
+ :param raise_exception: Boolean to raise or not NoOptionError, NoSectionError or RuntimeError.
414
+ :param default: the default value if not found.
415
+ :param check_config_table: if not set, avoid looking at config table even if it is called from server/daemon
416
+ :param session: The database session in use. Only used if not found in config file and if it is called from
417
+ server/daemon
418
+ :param use_cache: Boolean if the cache should be used. Only used if not found in config file and if it is called
419
+ from server/daemon
420
+ :param expiration_time: Time after that the cached value gets ignored. Only used if not found in config file and if
421
+ it is called from server/daemon
422
+
423
+ :returns: the configuration value.
424
+
425
+ :raises NoOptionError
426
+ :raises NoSectionError
427
+ :raises RuntimeError
428
+ :raises ValueError
429
+ """
430
+ return config_get(
431
+ section,
432
+ option,
433
+ raise_exception=raise_exception,
434
+ default=default,
435
+ check_config_table=check_config_table,
436
+ session=session,
437
+ use_cache=use_cache,
438
+ expiration_time=expiration_time,
439
+ convert_type_fnc=float,
440
+ )
441
+
442
+
443
+ @overload
444
+ def config_get_bool(
445
+ section: str,
446
+ option: str,
447
+ *,
448
+ check_config_table: bool = ...,
449
+ session: "Optional[Session]" = ...,
450
+ use_cache: bool = ...,
451
+ expiration_time: int = ...,
452
+ ) -> bool:
453
+ ...
454
+
455
+
456
+ @overload
457
+ def config_get_bool(
458
+ section: str,
459
+ option: str,
460
+ *,
461
+ default: bool = ...,
462
+ check_config_table: bool = ...,
463
+ session: "Optional[Session]" = ...,
464
+ use_cache: bool = ...,
465
+ expiration_time: int = ...,
466
+ ) -> bool:
467
+ ...
468
+
469
+
470
+ @overload
471
+ def config_get_bool(
472
+ section: str,
473
+ option: str,
474
+ raise_exception,
475
+ default: _T = ...,
476
+ *,
477
+ check_config_table: bool = ...,
478
+ session: "Optional[Session]" = ...,
479
+ use_cache: bool = ...,
480
+ expiration_time: int = ...,
481
+ ) -> Union[bool, _T]:
482
+ ...
483
+
484
+
485
+ def config_get_bool(
486
+ section,
487
+ option,
488
+ raise_exception=True,
489
+ default=None,
490
+ check_config_table=True,
491
+ session=None,
492
+ use_cache=True,
493
+ expiration_time=900,
494
+ ):
495
+ """
496
+ Return the boolean value for a given option in a section
497
+
498
+ :param section: the named section.
499
+ :param option: the named option.
500
+ :param raise_exception: Boolean to raise or not NoOptionError, NoSectionError or RuntimeError.
501
+ :param default: the default value if not found.
502
+ :param check_config_table: if not set, avoid looking at config table even if it is called from server/daemon
503
+ :param session: The database session in use. Only used if not found in config file and if it is called from
504
+ server/daemon
505
+ :param use_cache: Boolean if the cache should be used. Only used if not found in config file and if it is called
506
+ from server/daemon
507
+ :param expiration_time: Time after that the cached value gets ignored. Only used if not found in config file and if
508
+ it is called from server/daemon
509
+ .
510
+ :returns: the configuration value.
511
+
512
+ :raises NoOptionError
513
+ :raises NoSectionError
514
+ :raises RuntimeError
515
+ :raises ValueError
516
+ """
517
+ return config_get(
518
+ section,
519
+ option,
520
+ raise_exception=raise_exception,
521
+ default=default,
522
+ check_config_table=check_config_table,
523
+ session=session,
524
+ use_cache=use_cache,
525
+ expiration_time=expiration_time,
526
+ convert_type_fnc=_convert_to_boolean,
527
+ )
528
+
529
+
530
+ @overload
531
+ def config_get_list(
532
+ section: str,
533
+ option: str,
534
+ *,
535
+ check_config_table: bool = ...,
536
+ session: "Optional[Session]" = ...,
537
+ use_cache: bool = ...,
538
+ expiration_time: int = ...,
539
+ ) -> list[str]:
540
+ ...
541
+
542
+
543
+ @overload
544
+ def config_get_list(
545
+ section: str,
546
+ option: str,
547
+ *,
548
+ default: list[str] = ...,
549
+ check_config_table: bool = ...,
550
+ session: "Optional[Session]" = ...,
551
+ use_cache: bool = ...,
552
+ expiration_time: int = ...,
553
+ ) -> list[str]:
554
+ ...
555
+
556
+
557
+ @overload
558
+ def config_get_list(
559
+ section: str,
560
+ option: str,
561
+ raise_exception,
562
+ default: _T = ...,
563
+ *,
564
+ check_config_table: bool = ...,
565
+ session: "Optional[Session]" = ...,
566
+ use_cache: bool = ...,
567
+ expiration_time: int = ...,
568
+ ) -> Union[list[str], _T]:
569
+ ...
570
+
571
+
572
+ def config_get_list(
573
+ section,
574
+ option,
575
+ raise_exception=True,
576
+ default=None,
577
+ check_config_table=True,
578
+ session=None,
579
+ use_cache=True,
580
+ expiration_time=900,
581
+ ):
582
+ """
583
+ Return a list for a given option in a section
584
+
585
+ :param section: the named section.
586
+ :param option: the named option.
587
+ :param raise_exception: Boolean to raise or not NoOptionError, NoSectionError or RuntimeError.
588
+ :param default: the default value if not found.
589
+ :param check_config_table: if not set, avoid looking at config table even if it is called from server/daemon
590
+ :param session: The database session in use. Only used if not found in config file and if it is called from
591
+ server/daemon
592
+ :param use_cache: Boolean if the cache should be used. Only used if not found in config file and if it is called
593
+ from server/daemon
594
+ :param expiration_time: Time after that the cached value gets ignored. Only used if not found in config file and if
595
+ it is called from server/daemon
596
+ .
597
+ :returns: the configuration value.
598
+
599
+ :raises NoOptionError
600
+ :raises NoSectionError
601
+ :raises RuntimeError
602
+ :raises ValueError
603
+ """
604
+ value = config_get(
605
+ section,
606
+ option,
607
+ raise_exception=raise_exception,
608
+ default=default,
609
+ check_config_table=check_config_table,
610
+ session=session,
611
+ use_cache=use_cache,
612
+ expiration_time=expiration_time,
613
+ )
614
+ if isinstance(value, str):
615
+ value = __convert_string_to_list(value)
616
+ return value
617
+
618
+
619
+ def __convert_string_to_list(string: str) -> list[str]:
620
+ """
621
+ Convert a comma separated string to a list
622
+ :param string: The input string.
623
+
624
+ :returns: A list extracted from the string.
625
+ """
626
+ if not string or not string.strip():
627
+ return []
628
+ return [item.strip(' ') for item in string.split(',')]
629
+
630
+
631
+ def __config_get_table(
632
+ section: str,
633
+ option: str,
634
+ *,
635
+ raise_exception: bool = True,
636
+ default: _T = None,
637
+ clean_cached: bool = True,
638
+ session: "Optional[Session]" = None,
639
+ use_cache: bool = True,
640
+ expiration_time: int = 900,
641
+ convert_type_fnc: Optional[Callable[[str], _T]],
642
+ ) -> _T:
643
+ """
644
+ Search for a section-option configuration parameter in the configuration table
645
+
646
+ :param section: the named section.
647
+ :param option: the named option.
648
+ :param raise_exception: Boolean to raise or not ConfigNotFound.
649
+ :param default: the default value if not found.
650
+ :param session: The database session in use.
651
+ :param use_cache: Boolean if the cache should be used.
652
+ :param expiration_time: Time after that the cached value gets ignored.
653
+
654
+ :returns: the configuration value from the config table.
655
+
656
+ :raises ConfigNotFound
657
+ :raises DatabaseException
658
+ """
659
+ global __CONFIG
660
+ try:
661
+ from rucio.core.config import get as core_config_get
662
+ return core_config_get(section, option, default=default, session=session, use_cache=use_cache,
663
+ expiration_time=expiration_time, convert_type_fnc=convert_type_fnc)
664
+ except (ConfigNotFound, DatabaseException, ImportError) as err:
665
+ if raise_exception and default is None:
666
+ raise err
667
+ if clean_cached:
668
+ __CONFIG = None
669
+ return default
670
+
671
+
672
+ def config_get_options(section: str) -> list[str]:
673
+ """Return all options from a given section"""
674
+ return get_config().options(section)
675
+
676
+
677
+ def config_get_items(section: str) -> list[tuple[str, str]]:
678
+ """Return all (name, value) pairs from a given section"""
679
+ return get_config().items(section)
680
+
681
+
682
+ def config_remove_option(section: str, option: str) -> bool:
683
+ """
684
+ Remove the specified option from a given section.
685
+
686
+ :param section: Name of section in the Rucio config.
687
+ :param option: Name of option to remove from Rucio configuration.
688
+ :returns: True if the option existed in the configuration, False otherwise.
689
+
690
+ :raises NoSectionError: If the section does not exist.
691
+ """
692
+ return get_config().remove_option(section, option)
693
+
694
+
695
+ def config_set(section: str, option: str, value: str):
696
+ """
697
+ Set a configuration option in a given section.
698
+
699
+ :param section: Name of section in the Rucio config.
700
+ :param option: Name of option to set in the Rucio configuration.
701
+ :param value: New value for the option.
702
+
703
+ :raises NoSectionError: If the section does not exist.
704
+ """
705
+ return get_config().set(section, option, value)
706
+
707
+
708
+ def get_config_dirs():
709
+ """
710
+ Returns all available configuration directories in order:
711
+ - $RUCIO_HOME/etc/
712
+ - $VIRTUAL_ENV/etc/
713
+ - /opt/rucio/
714
+ """
715
+ configdirs = []
716
+
717
+ if 'RUCIO_HOME' in os.environ:
718
+ configdirs.append('%s/etc/' % os.environ['RUCIO_HOME'])
719
+
720
+ if 'VIRTUAL_ENV' in os.environ:
721
+ configdirs.append('%s/etc/' % os.environ['VIRTUAL_ENV'])
722
+
723
+ configdirs.append('/opt/rucio/etc/')
724
+
725
+ return configdirs
726
+
727
+
728
+ def get_lfn2pfn_algorithm_default():
729
+ """Returns the default algorithm name for LFN2PFN translation for this server."""
730
+ default_lfn2pfn = "hash"
731
+ try:
732
+ default_lfn2pfn = config_get('policy', 'lfn2pfn_algorithm_default')
733
+ except (configparser.NoOptionError, configparser.NoSectionError, RuntimeError):
734
+ pass
735
+ return default_lfn2pfn
736
+
737
+
738
+ def get_rse_credentials(path_to_credentials_file: Optional[Union[str, os.PathLike]] = None):
739
+ """ Returns credentials for RSEs. """
740
+
741
+ path = ''
742
+ if path_to_credentials_file: # Use specific file for this connect
743
+ path = path_to_credentials_file
744
+ else: # Use file defined in th RSEMgr
745
+ for confdir in get_config_dirs():
746
+ p = os.path.join(confdir, 'rse-accounts.cfg')
747
+ if os.path.exists(p):
748
+ path = p
749
+ try:
750
+ # Load all user credentials
751
+ with open(path) as cred_file:
752
+ credentials = json.load(cred_file)
753
+ except Exception as error:
754
+ raise exception.ErrorLoadingCredentials(error)
755
+ return credentials
756
+
757
+
758
+ __CONFIG = None
759
+
760
+
761
+ def get_config() -> configparser.ConfigParser:
762
+ """Factory function for the configuration class. Returns the ConfigParser instance."""
763
+ global __CONFIG
764
+ if __CONFIG is None:
765
+ __CONFIG = Config()
766
+ return __CONFIG.parser
767
+
768
+
769
+ def clean_cached_config():
770
+ """Deletes the cached config singleton instance."""
771
+ global __CONFIG
772
+ __CONFIG = None
773
+
774
+
775
+ class Config:
776
+ """
777
+ The configuration class reading the config file on init, located by using
778
+ get_config_dirs or the use of the RUCIO_CONFIG environment variable.
779
+ """
780
+ def __init__(self):
781
+ self.parser = configparser.ConfigParser()
782
+
783
+ if 'RUCIO_CONFIG' in os.environ:
784
+ self.configfile = os.environ['RUCIO_CONFIG']
785
+ else:
786
+ configs = [os.path.join(confdir, 'rucio.cfg') for confdir in get_config_dirs()]
787
+ self.configfile = next(iter(filter(os.path.exists, configs)), None)
788
+ if self.configfile is None:
789
+ raise RuntimeError('Could not load Rucio configuration file. '
790
+ 'Rucio looked in the following paths for a configuration file, in order:'
791
+ '\n\t' + '\n\t'.join(configs))
792
+
793
+ if not self.parser.read(self.configfile) == [self.configfile]:
794
+ raise RuntimeError('Could not load Rucio configuration file. '
795
+ 'Rucio tried loading the following configuration file:'
796
+ '\n\t' + self.configfile)