linuxfabrik-lib 4.0.0__tar.gz → 4.0.2__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.
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/PKG-INFO +1 -1
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/db_mysql.py +48 -2
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/endoflifedate.py +8 -8
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/linuxfabrik_lib.egg-info/PKG-INFO +1 -1
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/pyproject.toml +1 -1
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/url.py +21 -8
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/LICENSE +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/README.md +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/__init__.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/args.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/base.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/cache.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/db_sqlite.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/disk.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/distro.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/dmidecode.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/feedparser.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/globals.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/grassfish.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/huawei.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/human.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/icinga.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/infomaniak.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/jitsi.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/keycloak.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/lftest.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/librenms.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/linuxfabrik_lib.egg-info/SOURCES.txt +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/linuxfabrik_lib.egg-info/dependency_links.txt +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/linuxfabrik_lib.egg-info/requires.txt +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/linuxfabrik_lib.egg-info/top_level.txt +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/net.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/nextcloud.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/nodebb.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/powershell.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/psutil.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/qts.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/redfish.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/rocket.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/setup.cfg +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/shell.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/smb.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/time.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/txt.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/uptimerobot.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/veeam.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/version.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/wildfly.py +0 -0
- {linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/winrm.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: linuxfabrik-lib
|
|
3
|
-
Version: 4.0.
|
|
3
|
+
Version: 4.0.2
|
|
4
4
|
Summary: Python libraries used in various Linuxfabrik projects, including the 'Linuxfabrik Monitoring Plugins' project.
|
|
5
5
|
Author-email: "Linuxfabrik GmbH, Zurich, Switzerland" <info@linuxfabrik.ch>
|
|
6
6
|
License: This is free and unencumbered software released into the public domain.
|
|
@@ -15,7 +15,7 @@ import warnings
|
|
|
15
15
|
warnings.filterwarnings('ignore', category=UserWarning, module='pymysql')
|
|
16
16
|
|
|
17
17
|
__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
|
|
18
|
-
__version__ = '
|
|
18
|
+
__version__ = '2026051801'
|
|
19
19
|
|
|
20
20
|
import re
|
|
21
21
|
import sys
|
|
@@ -238,6 +238,14 @@ def connect(mysql_connection, **kwargs):
|
|
|
238
238
|
- If connection fails, the error message contains the reason for failure.
|
|
239
239
|
- `pymysql`'s `read_default_file` and `read_default_group` allow connection settings from a
|
|
240
240
|
`.cnf` file.
|
|
241
|
+
- After the connection is up, the function aligns the session's character set and collation
|
|
242
|
+
with the `mysql` system schema (`SET NAMES ... COLLATE ...`). This stops queries against
|
|
243
|
+
system tables like `mysql.user` and `mysql.global_priv` from aborting with ER 1267
|
|
244
|
+
("Illegal mix of collations") when the server's connection-collation default differs from
|
|
245
|
+
the column collations. On MariaDB 10.4+, `mysql.user` is a view over `mysql.global_priv`
|
|
246
|
+
whose JSON-derived columns return COERCIBLE results, so a plain `col = 'literal'` compare
|
|
247
|
+
breaks the moment `collation_connection` and the column collation differ. The alignment
|
|
248
|
+
is best-effort: on any error the connection stays usable with the server's defaults.
|
|
241
249
|
|
|
242
250
|
### Example
|
|
243
251
|
>>> mysql_connection = {
|
|
@@ -260,10 +268,48 @@ def connect(mysql_connection, **kwargs):
|
|
|
260
268
|
connect_timeout=mysql_connection.get('timeout', 3),
|
|
261
269
|
**kwargs,
|
|
262
270
|
)
|
|
263
|
-
return True, conn
|
|
264
271
|
except Exception as e:
|
|
265
272
|
return False, f'Connecting to DB failed: {e}'
|
|
266
273
|
|
|
274
|
+
_align_session_collation(conn)
|
|
275
|
+
return True, conn
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def _align_session_collation(conn):
|
|
279
|
+
"""Match `collation_connection` to the `mysql` system schema's default collation.
|
|
280
|
+
|
|
281
|
+
Without this, queries that compare a JSON-derived column from the `mysql.user`
|
|
282
|
+
view (e.g. `IS_ROLE = 'N'`, `plugin = 'mysql_native_password'`) abort with
|
|
283
|
+
ER 1267 ("Illegal mix of collations") when the server's connection collation
|
|
284
|
+
default doesn't match the schema's column collation. Looking up the schema's
|
|
285
|
+
own defaults from `information_schema.schemata` keeps this working across
|
|
286
|
+
MySQL/MariaDB versions and locale-specific installs (utf8mb3 on older
|
|
287
|
+
servers, utf8mb4_general_ci on most current ones, utf8mb4_uca1400_ai_ci on
|
|
288
|
+
MariaDB 10.10+). Best-effort: on any error the connection stays usable.
|
|
289
|
+
"""
|
|
290
|
+
try:
|
|
291
|
+
with conn.cursor(pymysql.cursors.DictCursor) as cursor:
|
|
292
|
+
cursor.execute(
|
|
293
|
+
'select default_character_set_name as cs, '
|
|
294
|
+
'default_collation_name as coll '
|
|
295
|
+
'from information_schema.schemata '
|
|
296
|
+
"where schema_name = 'mysql'"
|
|
297
|
+
)
|
|
298
|
+
row = cursor.fetchone()
|
|
299
|
+
if not row:
|
|
300
|
+
return
|
|
301
|
+
cs = (row.get('cs') or '').strip()
|
|
302
|
+
coll = (row.get('coll') or '').strip()
|
|
303
|
+
# Whitelist identifiers to keep the formatted `SET NAMES` safe from
|
|
304
|
+
# any caller-controlled value (the row comes from a system view, but
|
|
305
|
+
# defence in depth doesn't cost anything).
|
|
306
|
+
if not (re.match(r'^[A-Za-z0-9_]+$', cs) and re.match(r'^[A-Za-z0-9_]+$', coll)):
|
|
307
|
+
return
|
|
308
|
+
with conn.cursor() as cursor:
|
|
309
|
+
cursor.execute(f'set names {cs} collate {coll}')
|
|
310
|
+
except Exception:
|
|
311
|
+
pass
|
|
312
|
+
|
|
267
313
|
|
|
268
314
|
def get_all_status(conn):
|
|
269
315
|
"""
|
|
@@ -1614,8 +1614,8 @@ ENDOFLIFE_DATE = {
|
|
|
1614
1614
|
{ 'cycle': '11.8',
|
|
1615
1615
|
'eol': '2028-06-04',
|
|
1616
1616
|
'extendedSupport': '2033-10-22',
|
|
1617
|
-
'latest': '11.8.
|
|
1618
|
-
'latestReleaseDate': '2026-
|
|
1617
|
+
'latest': '11.8.7',
|
|
1618
|
+
'latestReleaseDate': '2026-05-14',
|
|
1619
1619
|
'lts': True,
|
|
1620
1620
|
'releaseDate': '2025-06-04'},
|
|
1621
1621
|
{ 'cycle': '11.7',
|
|
@@ -1645,8 +1645,8 @@ ENDOFLIFE_DATE = {
|
|
|
1645
1645
|
{ 'cycle': '11.4',
|
|
1646
1646
|
'eol': '2029-05-29',
|
|
1647
1647
|
'extendedSupport': '2033-01-16',
|
|
1648
|
-
'latest': '11.4.
|
|
1649
|
-
'latestReleaseDate': '2026-
|
|
1648
|
+
'latest': '11.4.11',
|
|
1649
|
+
'latestReleaseDate': '2026-05-14',
|
|
1650
1650
|
'lts': True,
|
|
1651
1651
|
'releaseDate': '2024-05-29'},
|
|
1652
1652
|
{ 'cycle': '11.3',
|
|
@@ -1684,8 +1684,8 @@ ENDOFLIFE_DATE = {
|
|
|
1684
1684
|
{ 'cycle': '10.11',
|
|
1685
1685
|
'eol': '2028-02-16',
|
|
1686
1686
|
'extendedSupport': '2028-02-16',
|
|
1687
|
-
'latest': '10.11.
|
|
1688
|
-
'latestReleaseDate': '2026-
|
|
1687
|
+
'latest': '10.11.17',
|
|
1688
|
+
'latestReleaseDate': '2026-05-14',
|
|
1689
1689
|
'lts': True,
|
|
1690
1690
|
'releaseDate': '2023-02-16'},
|
|
1691
1691
|
{ 'cycle': '10.10',
|
|
@@ -1723,8 +1723,8 @@ ENDOFLIFE_DATE = {
|
|
|
1723
1723
|
{ 'cycle': '10.6',
|
|
1724
1724
|
'eol': '2026-07-06',
|
|
1725
1725
|
'extendedSupport': '2029-08-23',
|
|
1726
|
-
'latest': '10.6.
|
|
1727
|
-
'latestReleaseDate': '2026-
|
|
1726
|
+
'latest': '10.6.26',
|
|
1727
|
+
'latestReleaseDate': '2026-05-14',
|
|
1728
1728
|
'lts': True,
|
|
1729
1729
|
'releaseDate': '2021-07-06'},
|
|
1730
1730
|
{ 'cycle': '10.5',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: linuxfabrik-lib
|
|
3
|
-
Version: 4.0.
|
|
3
|
+
Version: 4.0.2
|
|
4
4
|
Summary: Python libraries used in various Linuxfabrik projects, including the 'Linuxfabrik Monitoring Plugins' project.
|
|
5
5
|
Author-email: "Linuxfabrik GmbH, Zurich, Switzerland" <info@linuxfabrik.ch>
|
|
6
6
|
License: This is free and unencumbered software released into the public domain.
|
|
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "linuxfabrik-lib"
|
|
9
|
-
version = "4.0.
|
|
9
|
+
version = "4.0.2"
|
|
10
10
|
description = "Python libraries used in various Linuxfabrik projects, including the 'Linuxfabrik Monitoring Plugins' project."
|
|
11
11
|
readme = "README.md"
|
|
12
12
|
authors = [
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"""Get for example HTML or JSON from an URL."""
|
|
12
12
|
|
|
13
13
|
__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
|
|
14
|
-
__version__ = '
|
|
14
|
+
__version__ = '2026051802'
|
|
15
15
|
|
|
16
16
|
import base64
|
|
17
17
|
import json
|
|
@@ -35,13 +35,20 @@ except ImportError:
|
|
|
35
35
|
from . import txt
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
# stdlib ssl version names; '1.0' first because it is the most permissive minimum
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
38
|
+
# stdlib ssl version names; '1.0' first because it is the most permissive minimum.
|
|
39
|
+
# `ssl.TLSVersion` was added in Python 3.7. Build the dict only when available so
|
|
40
|
+
# `import lib.url` still works on older interpreters (e.g. RHEL 8's default `python3`
|
|
41
|
+
# = 3.6) - any plugin that doesn't actually use TLS version pinning then continues
|
|
42
|
+
# to work. Callers that pass `tls_min` / `tls_max` get a clearer RuntimeError in
|
|
43
|
+
# `_build_ssl_context()` instead of an AttributeError at import time.
|
|
44
|
+
_TLS_VERSIONS = {}
|
|
45
|
+
if hasattr(ssl, 'TLSVersion'):
|
|
46
|
+
_TLS_VERSIONS = {
|
|
47
|
+
'1.0': ssl.TLSVersion.TLSv1,
|
|
48
|
+
'1.1': ssl.TLSVersion.TLSv1_1,
|
|
49
|
+
'1.2': ssl.TLSVersion.TLSv1_2,
|
|
50
|
+
'1.3': ssl.TLSVersion.TLSv1_3,
|
|
51
|
+
}
|
|
45
52
|
|
|
46
53
|
|
|
47
54
|
def _redact_url(url):
|
|
@@ -59,6 +66,12 @@ def _build_ssl_context(insecure, tls_min, tls_max):
|
|
|
59
66
|
if insecure:
|
|
60
67
|
ctx.check_hostname = False
|
|
61
68
|
ctx.verify_mode = ssl.CERT_NONE
|
|
69
|
+
if tls_min is not None or tls_max is not None:
|
|
70
|
+
if not _TLS_VERSIONS:
|
|
71
|
+
raise RuntimeError(
|
|
72
|
+
'TLS version pinning (`tls_min` / `tls_max`) requires Python 3.7+ '
|
|
73
|
+
'(`ssl.TLSVersion`); this interpreter is too old.'
|
|
74
|
+
)
|
|
62
75
|
if tls_min is not None:
|
|
63
76
|
if tls_min not in _TLS_VERSIONS:
|
|
64
77
|
raise ValueError(
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{linuxfabrik_lib-4.0.0 → linuxfabrik_lib-4.0.2}/linuxfabrik_lib.egg-info/dependency_links.txt
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|