Compare commits

..

344 Commits

Author SHA1 Message Date
renovate[bot]
a177648f16
fix(deps): update dependency environs to v11.2.0 (#658)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-15 00:08:36 +01:00
18363422d3
ci: add read-only pull secret to security build 2024-11-14 20:51:59 +01:00
renovate[bot]
ceca157092
chore(docker): update python:3.13-alpine docker digest to fcbcbbe (#657)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-14 02:33:25 +01:00
renovate[bot]
0cd2fd3324
chore(docker): update python:3.13-alpine docker digest to bbe8d3f (#656)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-13 01:37:20 +01:00
renovate[bot]
d271a06c0b
fix(deps): update dependency environs to v11.1.0 (#655)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-11 22:41:48 +01:00
renovate[bot]
a8a381dea0
chore(deps): update dependency ruff to v0.7.3 (#654)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-11 01:43:25 +01:00
renovate[bot]
48a888d3f4
chore(deps): update python docker tag to v3.13 (#641)
BREAKING CHANGE: The support for Python 3.9 was removed.
2024-11-08 23:10:12 +01:00
renovate[bot]
e9ceac7b96
chore(deps): update docker.io/library/python docker tag to v3.13 (#640)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-08 22:12:38 +01:00
renovate[bot]
9c62f9a8b3
chore(deps): lock file maintenance (#652)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-08 22:03:43 +01:00
renovate[bot]
245fbf057c
chore(deps): update dependency pytest-cov to v6 (#649)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-05 19:59:45 +01:00
523eaa03b5
chore: drop python 3.8 support (#653)
BREAKING CHANGE: The support for Python 3.8 was dropped to support the latest `pytest-cov` release which requires at least Python 3.9
2024-11-05 19:46:41 +01:00
renovate[bot]
e9c4519490 chore(deps): update dependency ruff to v0.7.2 2024-11-04 02:53:44 +01:00
renovate[bot]
5ef42a2802 chore(deps): update dependency thegeeklab/hugo-geekdoc to v1.2.1 2024-11-04 02:53:29 +01:00
renovate[bot]
39bbc353e4
chore(deps): update quay.io/thegeeklab/hugo docker tag to v0.136.5 (#645)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-28 08:35:34 +01:00
renovate[bot]
537243688a
chore(deps): lock file maintenance (#648)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-28 08:28:43 +01:00
renovate[bot]
dcdb6b7604 chore(deps): update dependency ruff to v0.7.1 2024-10-28 02:55:42 +01:00
5ae518f4b7
cleanup docs pipeline 2024-10-27 21:21:10 +01:00
renovate[bot]
bd83cd118c
chore(deps): lock file maintenance (#642)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-27 21:08:42 +01:00
f47e738647
ci: add trivy and replace deprecated workflow syntax (#646) 2024-10-27 21:08:30 +01:00
468d452996 use context manager for tempfile 2024-10-21 20:43:32 +02:00
renovate[bot]
607f201888 chore(deps): update dependency ruff to v0.7.0 2024-10-21 20:43:32 +02:00
renovate[bot]
f2e78f8fd3 chore(docker): update python:3.12-alpine docker digest to 38e179a 2024-10-20 02:33:05 +02:00
renovate[bot]
ec335d389d
chore(deps): lock file maintenance (#639)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-07 21:11:42 +02:00
renovate[bot]
3022fde6f1 chore(deps): update dependency thegeeklab/hugo-geekdoc to v1.1.0 2024-10-07 03:32:25 +02:00
renovate[bot]
b0b0be6a5b chore(deps): update dependency ruff to v0.6.9 2024-10-07 03:32:10 +02:00
renovate[bot]
d1df941898
chore(deps): lock file maintenance (#634)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-03 14:27:33 +02:00
renovate[bot]
e0c53f628f chore(docker): update python:3.12-alpine docker digest to e75de17 2024-10-03 03:11:02 +02:00
renovate[bot]
31aceeaf0f chore(docker): update python:3.12-alpine docker digest to cf0a168 2024-10-02 05:28:15 +02:00
renovate[bot]
4cfbb678a7 chore(deps): update dependency ruff to v0.6.8 2024-09-30 02:48:20 +02:00
renovate[bot]
33b7007026
chore(deps): lock file maintenance (#632)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-23 11:18:48 +02:00
renovate[bot]
3869c65e59 chore(deps): update dependency ruff to v0.6.7 2024-09-23 05:32:36 +02:00
renovate[bot]
c1f5c5d408
fix(deps): update dependency prometheus-client to v0.21.0 (#630)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-22 20:34:37 +02:00
renovate[bot]
d7263f02a2
chore(deps): lock file maintenance (#629)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-20 08:50:22 +02:00
renovate[bot]
d8312af1d7 chore(deps): update devdeps non-major 2024-09-16 02:21:21 +02:00
renovate[bot]
4a330e0ef5 chore(docker): update python:3.12-alpine docker digest to 7130f75 2024-09-14 03:35:54 +02:00
renovate[bot]
fb50ce77ba chore(docker): update python:3.12-alpine docker digest to 7593fc6 2024-09-13 04:18:32 +02:00
renovate[bot]
2ea45bbf67 chore(docker): update python:3.12-alpine docker digest to e0e4d3d 2024-09-10 04:11:07 +02:00
renovate[bot]
0f36b0e97a
chore(deps): lock file maintenance (#624)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-09 18:09:29 +02:00
renovate[bot]
b7400f5d26 chore(deps): update dependency ruff to v0.6.4 2024-09-09 02:43:38 +02:00
renovate[bot]
140b58f933 chore(docker): update python:3.12-alpine docker digest to bb5d0ac 2024-09-08 05:19:52 +02:00
renovate[bot]
a544d7077b chore(docker): update python:3.12-alpine docker digest to aeff643 2024-09-05 04:13:23 +02:00
renovate[bot]
09bafef482
chore(deps): update quay.io/thegeeklab/hugo docker tag to v0.133.0 (#615)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-02 11:06:27 +02:00
renovate[bot]
f0b2105e53
chore(deps): update dependency thegeeklab/hugo-geekdoc to v1 (#618)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-02 07:48:03 +02:00
renovate[bot]
9435ee3dd8
chore(deps): lock file maintenance (#620)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-02 07:46:22 +02:00
renovate[bot]
bcf7bb7dd7 chore(deps): update dependency ruff to v0.6.3 2024-09-02 03:24:04 +02:00
renovate[bot]
392c81e9de
chore(deps): lock file maintenance (#617)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-26 08:25:42 +02:00
renovate[bot]
dc36c66b23 chore(deps): update dependency ruff to v0.6.2 2024-08-26 04:15:32 +02:00
renovate[bot]
5d23a1f14e
chore(deps): lock file maintenance (#614)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-19 11:17:54 +02:00
renovate[bot]
3874a167fc chore(deps): update dependency ruff to v0.6.1 2024-08-19 03:51:38 +02:00
renovate[bot]
71244a5e38
chore(deps): lock file maintenance (#599)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-12 09:01:40 +02:00
renovate[bot]
16faa55c14
fix(deps): update dependency proxmoxer to v2.1.0 (#611)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-12 09:01:29 +02:00
renovate[bot]
58095beb89 chore(deps): update dependency ruff to v0.5.7 2024-08-12 04:15:12 +02:00
renovate[bot]
cde5dd5f3b chore(docker): update python:3.12-alpine docker digest to c2f41e6 2024-08-08 03:30:33 +02:00
a2b27e8fe7
ci: fix notification step 2024-08-07 21:26:48 +02:00
renovate[bot]
3c061079f1 chore(docker): update python:3.12-alpine docker digest to 63094ab 2024-08-06 04:24:43 +02:00
renovate[bot]
2cc153f95b chore(deps): update dependency ruff to v0.5.6 2024-08-05 04:31:38 +02:00
renovate[bot]
5c2d75a92f chore(docker): update python:3.12-alpine docker digest to a0c22d8 2024-08-03 03:28:04 +02:00
renovate[bot]
e7f6ae7dbc chore(docker): update python:3.12-alpine docker digest to 2abecb7 2024-08-02 05:36:08 +02:00
renovate[bot]
be3d684896 chore(docker): update python:3.12-alpine docker digest to 7b76f1c 2024-08-02 03:14:08 +02:00
renovate[bot]
360f7d7d72 chore(deps): update devdeps non-major 2024-07-29 02:22:59 +02:00
renovate[bot]
c9b40e3083 chore(docker): update python:3.12-alpine docker digest to 7f15e22 2024-07-25 02:24:31 +02:00
renovate[bot]
ca84baa5d1 chore(docker): update python:3.12-alpine docker digest to 0032125 2024-07-24 04:04:21 +02:00
renovate[bot]
55506ca329 chore(docker): update python:3.12-alpine docker digest to dbb264b 2024-07-23 04:29:03 +02:00
renovate[bot]
cc08e7ecf4 chore(deps): update devdeps non-major 2024-07-22 05:17:44 +02:00
renovate[bot]
8b60a8c870 chore(deps): update dependency ruff to v0.5.2 2024-07-15 02:59:28 +02:00
renovate[bot]
8f1842c7b2 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.47.0 2024-07-15 02:58:48 +02:00
renovate[bot]
84ff5a8d46 chore(docker): update python:3.12-alpine docker digest to 0bd77ae 2024-07-11 05:39:36 +02:00
renovate[bot]
54104c0907 chore(docker): update python:3.12-alpine docker digest to 29d92b7 2024-07-11 02:14:16 +02:00
renovate[bot]
659a5e261c
fix(deps): update dependency jsonschema to v4.23.0 (#593)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-09 08:15:58 +02:00
renovate[bot]
c88e673dc8 chore(docker): update python:3.12-alpine docker digest to b7662fc 2024-07-09 02:14:36 +02:00
renovate[bot]
c05edbbcf3
chore(deps): update quay.io/thegeeklab/wp-docker-buildx docker tag to v5 (#592)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-08 13:51:38 +02:00
renovate[bot]
d78dcf85dc
chore(deps): lock file maintenance (#587)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-08 08:25:12 +02:00
renovate[bot]
1be10545b3 chore(deps): update dependency ruff to v0.5.0 2024-07-01 02:37:08 +02:00
renovate[bot]
d25cefc609 chore(docker): update python:3.12-alpine docker digest to ff870bf 2024-06-28 02:18:47 +02:00
renovate[bot]
913090d40b chore(deps): update dependency ruff to v0.4.10 2024-06-24 02:33:00 +02:00
renovate[bot]
86f71e859f chore(docker): update python:3.12-alpine docker digest to dc09596 2024-06-21 07:17:18 +02:00
renovate[bot]
8980a0a344 chore(deps): update dependency ruff to v0.4.9 2024-06-17 03:06:09 +02:00
renovate[bot]
e3618be472 chore(docker): update python:3.12-alpine docker digest to a982997 2024-06-15 03:48:23 +02:00
renovate[bot]
c6ccccba55
chore(deps): update quay.io/thegeeklab/hugo docker tag to v0.127.0 (#582)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-10 07:27:58 +02:00
renovate[bot]
372f09bb9d chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.46.0 2024-06-10 03:14:06 +02:00
renovate[bot]
0c670947f0 chore(deps): update devdeps non-major 2024-06-10 03:13:00 +02:00
renovate[bot]
19a43acc93 chore(docker): update python:3.12-alpine docker digest to d24ed56 2024-06-08 02:48:43 +02:00
renovate[bot]
1da664888f chore(docker): update python:3.12-alpine docker digest to 32385e6 2024-06-06 04:02:12 +02:00
renovate[bot]
b9fe632851
fix(deps): update dependency requests to v2.32.3 (#579)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-05 09:37:17 +02:00
renovate[bot]
78050a80b3
chore(deps): lock file maintenance (#577)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-05 09:17:27 +02:00
dependabot[bot]
1d42b9d058
chore(deps): bump requests from 2.31.0 to 2.32.2 (#575) 2024-06-05 09:17:18 +02:00
renovate[bot]
5c3729e7c7 chore(deps): update dependency ruff to v0.4.7 2024-06-03 03:23:46 +02:00
renovate[bot]
2f5661a529
chore(deps): lock file maintenance (#574)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-01 13:19:08 +02:00
renovate[bot]
f79e7a1248 chore(deps): update devdeps non-major 2024-05-27 04:07:03 +02:00
renovate[bot]
2fd71a96c7 chore(docker): update python:3.12-alpine docker digest to 5365725 2024-05-23 05:48:10 +02:00
renovate[bot]
62c6d6fdb7
chore(deps): lock file maintenance (#569)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-17 09:37:10 +02:00
renovate[bot]
ac3ff2d9df
chore(deps): update quay.io/thegeeklab/hugo docker tag to v0.125.7 (#570)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-14 15:06:38 +02:00
renovate[bot]
7cdc20a555 chore(deps): update dependency ruff to v0.4.4 2024-05-13 03:28:40 +02:00
renovate[bot]
8e71ce23e5
chore(deps): lock file maintenance (#567)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-07 12:14:52 +02:00
renovate[bot]
0577f10fad chore(deps): update dependency ruff to v0.4.3 2024-05-06 05:12:35 +02:00
renovate[bot]
d023f7e9e9
fix(deps): update dependency jsonschema to v4.22.0 (#565)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-02 10:10:10 +02:00
renovate[bot]
762547a0da
chore(deps): update devdeps non-major (#564)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Robert Kaussow <mail@thegeeklab.de>
2024-04-29 10:47:35 +02:00
renovate[bot]
8d9d59351e
chore(deps): lock file maintenance (#562)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-29 10:27:48 +02:00
renovate[bot]
8239461432 chore(deps): update dependency ruff to v0.4.1 2024-04-22 05:09:40 +00:00
renovate[bot]
ff3f401786 chore(deps): update dependency ruff to v0.3.7 2024-04-15 03:40:04 +00:00
renovate[bot]
04ce915e07
chore(deps): lock file maintenance (#551)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-12 09:17:38 +02:00
renovate[bot]
791c2482c0 chore(docker): update python:3.12-alpine docker digest to ef09762 2024-04-11 05:09:23 +00:00
renovate[bot]
2c7c767830 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.45.0 2024-04-08 06:34:30 +00:00
renovate[bot]
b7ec5ba60e chore(deps): update dependency ruff to v0.3.5 2024-04-08 03:23:21 +00:00
renovate[bot]
658b9b2502 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.44.3 2024-04-01 03:18:57 +00:00
renovate[bot]
9bcc45932f
chore(deps): update quay.io/thegeeklab/wp-docker-buildx docker tag to v4 (#556)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-27 08:55:31 +01:00
renovate[bot]
d504297a08 chore(docker): update python:3.12-alpine docker digest to c7eb5c9 2024-03-26 08:03:20 +00:00
renovate[bot]
e541271ffd
chore(deps): update dependency pytest-cov to v5 (#553)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-25 08:34:16 +01:00
renovate[bot]
9d26517a6b chore(deps): update devdeps non-major 2024-03-25 03:06:53 +00:00
renovate[bot]
ff21ee3db6
chore(deps): update quay.io/thegeeklab/hugo docker tag to v0.124.1 (#552)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-21 08:48:17 +01:00
renovate[bot]
e76f37f143 chore(deps): update dependency ruff to v0.3.3 2024-03-18 04:06:51 +00:00
renovate[bot]
cc158dddf6 chore(docker): update python:3.12-alpine docker digest to 25a82f6 2024-03-17 03:01:47 +00:00
0590089098
ci: fix deprecated ruff command 2024-03-12 20:52:57 +01:00
renovate[bot]
d5cdd92242
chore(deps): lock file maintenance (#548)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-11 09:39:57 +01:00
renovate[bot]
e082d6c7cb chore(deps): update devdeps non-major 2024-03-11 07:17:03 +00:00
renovate[bot]
7966c1c11e chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.44.2 2024-03-11 03:16:51 +00:00
renovate[bot]
a2f513156a
chore(deps): update dependency ruff to v0.3.1 (#543)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Robert Kaussow <mail@thegeeklab.de>
2024-03-07 11:50:43 +01:00
renovate[bot]
a2485d83eb
fix(deps): update dependency environs to v11 (#545)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-07 11:01:13 +01:00
renovate[bot]
4b3249b9a3
chore(deps): lock file maintenance (#544)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-07 11:01:05 +01:00
renovate[bot]
3f7d44a7d2
chore(deps): lock file maintenance (#541)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-26 10:43:30 +01:00
renovate[bot]
db8b62c323 chore(deps): update dependency pytest to v8.0.2 2024-02-26 04:12:25 +00:00
renovate[bot]
bc05b2ad38 chore(deps): update devdeps non-major 2024-02-19 04:40:06 +00:00
renovate[bot]
c324ab330f
fix(deps): update dependency prometheus-client to v0.20.0 (#539)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-15 12:29:41 +01:00
fa06bcbdf1
[skip ci] revert renovate automerge config 2024-02-15 12:23:11 +01:00
renovate[bot]
7b72b07157
chore(deps): update quay.io/thegeeklab/hugo docker tag to v0.122.0 (#538)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-11 16:53:26 +01:00
ad9ffeab64
enable renovate on automerge branches 2024-02-09 23:08:34 +01:00
renovate[bot]
14788622c7 chore(docker): update python:3.12-alpine docker digest to 1a05012 2024-02-09 06:12:15 +00:00
renovate[bot]
aed5373c06
fix(deps): update dependency ruamel.yaml to v0.18.6 (#536)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-07 09:48:25 +01:00
7e7bd413a8
chore: bump ruff to v0.2.1 (#535) 2024-02-06 09:34:49 +01:00
renovate[bot]
028d733d87
chore(deps): update dependency pytest to v8 (#533)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-31 09:05:21 +01:00
renovate[bot]
e5c599472b chore(docker): update python:3.12-alpine docker digest to 14cfc61 2024-01-29 07:29:53 +00:00
1c3e4fc7e7
fix: split tag string at semicolon instead of comma (#532) 2024-01-24 12:50:39 +01:00
renovate[bot]
aa3a82ae08
chore(deps): update quay.io/thegeeklab/wp-docker-buildx docker tag to v3 (#531)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-22 11:37:44 +01:00
renovate[bot]
395623b08b chore(deps): update dependency ruff to v0.1.14 2024-01-22 03:33:26 +00:00
renovate[bot]
76ec43e1f8
fix(deps): update dependency jsonschema to v4.21.1 (#529)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-20 15:12:57 +01:00
renovate[bot]
d470109ddc chore(docker): update python:3.12-alpine docker digest to 801b54e 2024-01-19 22:30:16 +00:00
renovate[bot]
cae9a4d815 chore(docker): update python:3.12-alpine docker digest to 4a156f7 2024-01-19 06:55:54 +00:00
renovate[bot]
9b1a450b48
fix(deps): update dependency jsonschema to v4.21.0 (#526)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-18 10:22:01 +01:00
renovate[bot]
5cb73241f9 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.44.1 2024-01-16 02:08:03 +00:00
renovate[bot]
f39aea6c82
fix(deps): update dependency anyconfig to v0.14.0 (#523)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-15 21:55:43 +01:00
renovate[bot]
793ec14b80
chore(deps): update dependency ruff to v0.1.13 (#524)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Robert Kaussow <mail@thegeeklab.de>
2024-01-15 20:39:42 +01:00
renovate[bot]
55378ceea6
fix(deps): update dependency environs to v10.3.0 (#522)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-12 08:30:11 +01:00
renovate[bot]
f3f9dac6fe
fix(deps): update dependency environs to v10.2.0 (#521)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-10 08:38:42 +01:00
renovate[bot]
f2b770d1f8
fix(deps): update dependency environs to v10.1.0 (#520)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-09 15:03:27 +01:00
renovate[bot]
63ee9caf5d chore(deps): update dependency ruff to v0.1.11 2024-01-08 04:30:37 +00:00
renovate[bot]
ebf54473bd
chore(deps): update quay.io/thegeeklab/hugo docker tag to v0.121.2 (#518)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-07 20:41:44 +01:00
renovate[bot]
8d7a30a0b1
chore(deps): lock file maintenance (#511)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-01 18:21:10 +01:00
renovate[bot]
1e3d5a0b18 chore(deps): update dependency pytest to v7.4.4 2024-01-01 11:15:32 +00:00
renovate[bot]
e356f64bfd
fix(deps): update dependency environs to v10 (#512)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-27 11:10:46 +01:00
renovate[bot]
5c0c893915 chore(deps): update dependency ruff to v0.1.9 2023-12-25 03:11:13 +00:00
88eac83007
disable renovate for python test matrix in ci 2023-12-24 00:03:59 +01:00
3de899b6cd
use list style synatx and cleanup (#514) 2023-12-23 23:26:57 +01:00
renovate[bot]
b603af1380 chore(deps): update dependency ruff to v0.1.8 2023-12-18 04:48:01 +00:00
8c2b3ad968
cleanup unused env vars in ci 2023-12-17 14:08:03 +01:00
renovate[bot]
a76a6f40e3 chore(deps): update dependency ruff to v0.1.7 2023-12-11 03:32:56 +00:00
renovate[bot]
1dc51232cc chore(docker): update python:3.12-alpine docker digest to c793b92 2023-12-09 09:06:53 +00:00
b6fd9ccf83
ci: exclude dockerhub from linkcheck due to rate limiting 2023-12-07 09:08:30 +01:00
renovate[bot]
3d85f78054
chore(deps): update quay.io/thegeeklab/wp-docker-buildx docker tag to v2 (#508)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-07 08:39:48 +01:00
renovate[bot]
12e70d508d chore(docker): update python:3.12-alpine docker digest to 09f18c1 2023-12-04 21:15:51 +00:00
renovate[bot]
e244d4ddaf
chore(deps): lock file maintenance (#506)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-04 21:19:29 +01:00
518f8d428b
fix settings for required status checks 2023-12-04 21:01:54 +01:00
renovate[bot]
4811621be5
fix(deps): update dependency prometheus-client to v0.19.0 (#505)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-21 08:44:25 +01:00
renovate[bot]
9d1ab01643
chore(deps): lock file maintenance (#500)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-20 09:02:04 +01:00
renovate[bot]
ba3456b53a
fix(deps): update dependency jsonschema to v4.20.0 (#503)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-20 09:01:21 +01:00
renovate[bot]
ce708b94cb chore(deps): update dependency ruff to v0.1.6 2023-11-20 03:38:17 +00:00
renovate[bot]
2088efbe23 chore(deps): update dependency ruff to v0.1.5 2023-11-13 04:38:37 +00:00
f13de60e06
chore: drop yapf and favor of the ruff formatter (#501) 2023-11-10 14:50:58 +01:00
renovate[bot]
fd85dc598b chore(deps): update dependency ruff to v0.1.4 2023-11-06 03:03:08 +00:00
0756afda02
ci: cleanup matrix build name (#498) 2023-11-04 16:24:31 +01:00
renovate[bot]
2a3468b604
fix(deps): update dependency ruamel.yaml to v0.18.5 (#497)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-04 16:03:19 +01:00
renovate[bot]
2baaf1e07b
chore(deps): lock file maintenance (#490)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-31 20:56:36 +01:00
renovate[bot]
334caabe1f
fix(deps): update dependency ruamel.yaml to v0.18.3 (#491)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-31 20:56:28 +01:00
renovate[bot]
a1643b3a9f
fix(deps): update dependency jsonschema to v4.19.2 (#495)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-31 20:43:07 +01:00
renovate[bot]
bb23593f5c
fix(deps): update dependency prometheus-client to v0.18.0 (#496)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-31 20:07:47 +01:00
renovate[bot]
42e0a5f726 chore(deps): update devdeps non-major 2023-10-30 04:45:54 +00:00
renovate[bot]
b0cc925b55 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.44.0 2023-10-29 12:17:46 +00:00
renovate[bot]
5bc82508c8 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.43.0 2023-10-27 15:50:49 +00:00
renovate[bot]
c84035a405 chore(deps): update devdeps non-major 2023-10-23 03:22:42 +00:00
renovate[bot]
da28d6dd9c chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.42.0 2023-10-21 18:07:45 +00:00
renovate[bot]
1694771542
fix(deps): update dependency ruamel.yaml to v0.17.40 (#487)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-21 15:33:48 +02:00
renovate[bot]
de9aac38ca chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.41.3 2023-10-20 13:06:55 +00:00
renovate[bot]
72d0e49028
fix(deps): update dependency ruamel.yaml to v0.17.39 (#484)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-20 08:59:43 +02:00
renovate[bot]
a5755e03af
chore(docker): update python:3.12-alpine docker digest to a5d1738 (#483)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-19 22:43:23 +02:00
renovate[bot]
79c3e8683b
chore(deps): lock file maintenance (#485)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-19 22:32:15 +02:00
628244f9ad
ci: fix changelog generation 2023-10-18 13:59:28 +02:00
8f6c394a21
chore: replace linkcheck by lychee (#482)
* chore: replace linkcheck by lychee

* fix step order in docs workflow
2023-10-16 21:34:42 +02:00
e98439b9ff
chore: replace git-chglog by git-sv (#481) 2023-10-16 15:42:36 +02:00
renovate[bot]
1d9a82d774
chore(deps): lock file maintenance (#478)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-16 14:28:38 +02:00
40bfa21f72
feat: add support for python 3.12 (#480)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-16 14:15:57 +02:00
cb5fa8409e
fix: remove deprecated distutils (#479) 2023-10-16 12:11:22 +02:00
renovate[bot]
ab9d0de2f5 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.41.2 2023-10-11 01:16:35 +00:00
renovate[bot]
f957869179
fix(deps): update dependency ruamel.yaml to v0.17.35 (#474)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-09 14:40:13 +02:00
renovate[bot]
ef86a0000e
chore(deps): lock file maintenance (#476)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-09 14:39:56 +02:00
renovate[bot]
958c89f2f9 chore(deps): update dependency ruff to v0.0.292 2023-10-09 04:32:39 +00:00
renovate[bot]
8e690232e3 chore(docker): update python:3.11-alpine docker digest to 3e73c0b 2023-10-03 16:58:39 +00:00
bdd940131d
ci: run git unshallow conditionally (#470) 2023-10-02 14:13:46 +02:00
renovate[bot]
bc7b5ebf47
chore(deps): lock file maintenance (#469)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-02 11:46:11 +02:00
renovate[bot]
a370bd26fd
fix(deps): update dependency ruamel.yaml to v0.17.33 (#467)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-02 11:14:21 +02:00
renovate[bot]
4bdfcc3256 chore(docker): update python:3.11-alpine docker digest to cd311c6 2023-09-29 19:40:16 +00:00
renovate[bot]
ae62da0ec2
chore(deps): lock file maintenance (#466)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-27 13:47:41 +02:00
renovate[bot]
3b4707e06c
fix(deps): update dependency jsonschema to v4.19.1 (#464)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-27 13:47:32 +02:00
4c35cc706c
ci: use secret for s3 endpoint 2023-09-26 21:40:33 +02:00
e5f3947e7c
docs: drop codecov badge 2023-09-25 09:27:03 +02:00
renovate[bot]
7096aefb74 chore(deps): update devdeps non-major 2023-09-25 04:28:23 +00:00
renovate[bot]
3dc7405378
chore(deps): lock file maintenance (#456)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-19 09:01:13 +02:00
35bfa8bc6a
feat: add option to authenticate with api token instead of password (#460)
Co-authored-by: Bruno MATEU <pro+github@brunomat.eu>
Co-authored-by: Bruno MATEU <mateubruno@gmail.com>
2023-09-19 09:00:30 +02:00
renovate[bot]
a6d128d605 chore(deps): update dependency ruff to v0.0.290 2023-09-18 03:55:26 +00:00
renovate[bot]
d7bc938ecb chore(deps): update dependency pytest to v7.4.2 2023-09-11 04:59:21 +00:00
3eaf162858
ci: use full clone for test workflow to fix version detection (#461) 2023-09-05 12:02:09 +02:00
renovate[bot]
5e7a371725 chore(deps): update devdeps non-major 2023-09-04 04:30:29 +00:00
renovate[bot]
dcfdcb6272 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.41.1 2023-09-04 00:39:44 +00:00
renovate[bot]
74a5a67112 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.41.0 2023-09-01 01:47:27 +00:00
renovate[bot]
62d41df763 chore(deps): update dependency ruff to v0.0.286 2023-08-28 04:28:58 +00:00
renovate[bot]
b88a9e0c55 chore(docker): update python:3.11-alpine docker digest to 5d769f9 2023-08-26 10:12:33 +00:00
99f426263b
fix: use poetry-dynamic-versioning backend wrapper 2023-08-25 00:28:41 +02:00
8be6b5b824
add back pytest to ci 2023-08-24 23:51:54 +02:00
c7faac94e4
cleanup missed drone ci refs 2023-08-24 22:43:29 +02:00
renovate[bot]
c8c1ba033d
chore(deps): lock file maintenance (#451)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-24 22:28:44 +02:00
renovate[bot]
37440e080c
chore(deps): update dependency ruff to v0.0.285 (#452)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Robert Kaussow <mail@thegeeklab.de>
2023-08-24 22:27:14 +02:00
202d19d8df
ci: migrate to woodpecker (#453) 2023-08-24 22:14:30 +02:00
renovate[bot]
7090981489 chore(deps): update dependency ruff to v0.0.284 2023-08-14 04:06:17 +00:00
renovate[bot]
c55705d438 chore(docker): update python:3.11-alpine docker digest to 603975e 2023-08-09 16:54:37 +00:00
renovate[bot]
6608cc6a8a
fix(deps): update dependency jsonschema to v4.19.0 (#447)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-09 07:34:37 +02:00
renovate[bot]
d3c07449c1
chore(deps): lock file maintenance (#446)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-09 07:33:39 +02:00
renovate[bot]
37f09b0ded chore(docker): update python:3.11-alpine docker digest to bd16cc5 2023-08-08 10:14:34 +00:00
renovate[bot]
ad39a58124 chore(deps): update dependency ruff to v0.0.282 2023-08-07 03:24:34 +00:00
renovate[bot]
f802637149
fix(deps): update dependency jsonschema to v4.18.6 (#444)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-05 15:50:12 +02:00
renovate[bot]
91b3b5143b
fix(deps): update dependency jsonschema to v4.18.5 (#443)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-02 22:00:22 +02:00
renovate[bot]
40ae246fc8
chore(deps): lock file maintenance (#440)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-02 10:48:16 +02:00
renovate[bot]
5e7e58cbd2 chore(deps): update dependency ruff to v0.0.280 2023-07-24 04:23:10 +00:00
renovate[bot]
a38285a2c5
fix(deps): update dependency jsonschema to v4.18.4 (#433)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-23 13:06:17 +02:00
c6b1734ad1
chore: drop support for python 3.7 (#441)
BREAKING CHANGE: The support for Python 3.7 was removed.
2023-07-23 12:42:41 +02:00
renovate[bot]
8b99e80fce chore(deps): update dependency ruff to v0.0.278 2023-07-17 03:34:47 +00:00
renovate[bot]
4f01e9fdb5 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.40.1 2023-07-12 10:20:53 +00:00
renovate[bot]
e8c72c63fc chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.40.0 2023-07-11 22:09:25 +00:00
renovate[bot]
f2a87114c6
chore(deps): lock file maintenance (#426)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-11 21:28:25 +02:00
renovate[bot]
f29ac553ae
fix(deps): update dependency prometheus-client to v0.17.1 (#435)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-11 21:28:17 +02:00
2d415caca6
ci: bump hugo to v0.115.2 (#436) 2023-07-11 21:28:06 +02:00
renovate[bot]
0700c91f00 chore(deps): update dependency ruff to v0.0.277 2023-07-10 04:52:45 +00:00
renovate[bot]
9eb888fac8 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.7 2023-07-03 14:14:53 +00:00
renovate[bot]
31c0e1b166 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.6 2023-06-28 21:23:39 +00:00
renovate[bot]
63da0a31c4
chore(deps): update devdeps non-major (#430)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Robert Kaussow <mail@thegeeklab.de>
2023-06-28 09:54:46 +02:00
renovate[bot]
bb1370f57c chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.5 2023-06-23 12:01:44 +00:00
372911d63c
ci: bump hugo to v0.114.0 (#429) 2023-06-23 11:13:57 +02:00
a8b4ae4827
docs: replace socialmedia image (#427) 2023-06-20 14:30:41 +02:00
renovate[bot]
b3717c2b79 chore(deps): update devdeps non-major 2023-06-19 04:44:12 +00:00
renovate[bot]
3c86756779
chore(deps): lock file maintenance (#418)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-17 15:23:14 +02:00
renovate[bot]
3e346c21ad
fix(deps): update dependency ruamel.yaml to v0.17.32 (#417)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-17 15:23:06 +02:00
renovate[bot]
94597d9a84 chore(docker): update python:3.11-alpine docker digest to 25df32b 2023-06-15 16:11:41 +00:00
renovate[bot]
d70ff324a7 chore(deps): update devdeps non-major 2023-06-12 04:14:14 +00:00
renovate[bot]
044ed59b05 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.4 2023-06-09 09:21:45 +00:00
renovate[bot]
a8af0597bd chore(docker): update python:3.11-alpine docker digest to 995c7fc 2023-06-08 05:20:04 +00:00
renovate[bot]
ae0e8fa87f chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.3 2023-06-05 14:57:20 +00:00
renovate[bot]
3838826442 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.2 2023-05-29 12:20:11 +00:00
renovate[bot]
46ae2c79e0
fix(deps): update dependency prometheus-client to v0.17.0 (#412)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-29 12:27:18 +02:00
renovate[bot]
8915a480c1
fix(deps): update dependency ruamel.yaml to v0.17.28 (#413)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-29 12:08:55 +02:00
renovate[bot]
b00845735f
chore(deps): lock file maintenance (#415)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-29 11:40:35 +02:00
renovate[bot]
5e9a3b2426
fix(deps): update dependency requests to v2.31.0 [security] (#411)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-29 11:38:21 +02:00
renovate[bot]
6e118aa4f9
chore(deps): update devdeps non-major (#408) 2023-05-28 23:07:37 +02:00
renovate[bot]
553220aed0
chore(deps): lock file maintenance (#409)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-28 15:30:50 +02:00
111f856cea
chore: remove poetry experimental.new-installer flag (#414) 2023-05-28 15:19:10 +02:00
etfeet
8dad3ae9dd
feat: add node hostname info to discovery info logging (#388)
Co-authored-by: Robert Kaussow <xoxys@rknet.org>
2023-05-14 19:55:03 +02:00
renovate[bot]
edf8082b31
chore(deps): lock file maintenance (#382)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-14 18:54:06 +02:00
renovate[bot]
b0079e33f5
fix(deps): update dependency requests to v2.30.0 (#404)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-14 18:53:48 +02:00
renovate[bot]
546c10020c
fix(deps): update dependency ruamel.yaml to v0.17.26 (#399)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-13 11:11:48 +02:00
renovate[bot]
46ff967f22 chore(docker): update python:3.11-alpine docker digest to 4e8e9a5 2023-05-12 22:18:07 +00:00
renovate[bot]
c11a7b4bb4 chore(docker): update python:3.11-alpine docker digest to 2f2dadb 2023-05-12 10:50:26 +00:00
renovate[bot]
ed58d04879 chore(deps): update dependency ruff to v0.0.265 2023-05-08 06:04:05 +00:00
renovate[bot]
742307e27e chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.1 2023-05-04 13:03:34 +00:00
renovate[bot]
83e67d5b6f chore(docker): update python:3.11-alpine docker digest to 7210235 2023-05-03 22:26:46 +00:00
renovate[bot]
ea48be1db2 chore(docker): update python:3.11-alpine docker digest to 06a3f7b 2023-05-03 14:47:18 +00:00
f0959a0dc0
fix bare url in contribution file (#401) 2023-05-03 09:35:01 +02:00
renovate[bot]
5d2d924197 chore(deps): update dependency ruff to v0.0.263 2023-05-01 05:52:28 +00:00
renovate[bot]
3926d55b62
fix(deps): update dependency requests to v2.29.0 (#397)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-27 08:46:52 +02:00
renovate[bot]
6a3b3f5df8 chore(deps): update devdeps non-major 2023-04-24 05:05:29 +00:00
renovate[bot]
f4e7d0dfd1 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.39.0 2023-04-20 03:50:10 +00:00
renovate[bot]
f2f0abdf47 chore(deps): update dependency pytest to v7.3.1 2023-04-17 14:38:12 +00:00
006360cc2c
ci: switch to new codecov uploader (#393) 2023-04-17 16:09:48 +02:00
renovate[bot]
e58de90d69 chore(deps): update devdeps non-major 2023-04-10 05:43:08 +00:00
renovate[bot]
37751a173a chore(docker): update python:3.11-alpine docker digest to 507818d 2023-04-08 00:53:05 +00:00
renovate[bot]
d46ff8b1c1 chore(docker): update python:3.11-alpine docker digest to 5405826 2023-04-06 07:59:15 +00:00
renovate[bot]
01f3fceae8 chore(docker): update python:3.11-alpine docker digest to 4b4078a 2023-03-30 07:00:22 +00:00
renovate[bot]
d2f804af98 chore(docker): update python:3.11-alpine docker digest to e8cd6ca 2023-03-30 04:48:39 +00:00
renovate[bot]
4ecfc8e06c chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.38.1 2023-03-27 21:38:39 +00:00
renovate[bot]
0fe543624f chore(docker): update python:3.11-alpine docker digest to 8af856d 2023-03-27 04:01:25 +00:00
renovate[bot]
7610ab8814 chore(deps): update dependency ruff to v0.0.259 2023-03-27 02:35:18 +00:00
renovate[bot]
562498a420 chore(docker): update python:3.11-alpine docker digest to 506eed4 2023-03-23 19:52:13 +00:00
renovate[bot]
44129fa1d3
fix(deps): update dependency python-json-logger to v2.0.7 (#377) 2023-03-20 11:17:17 +01:00
renovate[bot]
04dc8b7cc6
chore(deps): lock file maintenance (#368) 2023-03-20 10:36:38 +01:00
renovate[bot]
a7cfd6d520
chore(deps): update dependency ruff to v0.0.257 (#378) 2023-03-20 10:34:12 +01:00
renovate[bot]
97166b27de chore(docker): update python:3.11-alpine docker digest to 741e650 2023-03-14 13:32:48 +00:00
49c02d50e1
chore: exclude ruff linter rule UP038 (#375) 2023-03-07 14:21:51 +01:00
renovate[bot]
f4a94a7bd5 chore(deps): update devdependencies (non-major) 2023-03-06 06:00:40 +00:00
renovate[bot]
8522c960cd chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.38.0 2023-03-04 23:57:12 +00:00
renovate[bot]
f9be89e9c2 chore(deps): update dependency ruff to v0.0.252 2023-02-27 06:04:41 +00:00
renovate[bot]
39f22a3b11 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.37.5 2023-02-27 02:51:35 +00:00
renovate[bot]
eff27d075b chore(docker): update python:3.11-alpine docker digest to 1a5c146 2023-02-25 15:31:47 +00:00
renovate[bot]
4c15718b7e
chore(deps): update dependency ruff to v0.0.247 (#367) 2023-02-20 10:49:59 +01:00
renovate[bot]
d1edfddfae chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.37.4 2023-02-17 13:52:59 +00:00
renovate[bot]
3b2aba6636 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.37.3 2023-02-16 14:27:00 +00:00
a3fa0ef215
refctor: migrate flake8 to ruff python linter (#363) 2023-02-12 15:11:15 +01:00
renovate[bot]
d896f7d22d chore(docker): update python:3.11-alpine docker digest to 8463061 2023-02-11 16:11:43 +00:00
f76d25e3d0
ci: bump container build plugin to drone-docker-buildx:23 (#361) 2023-02-09 19:41:57 +01:00
renovate[bot]
258e186311 chore(docker): update python:3.11-alpine docker digest to deb0f63 2023-02-09 09:07:41 +00:00
fc530c9f61
fix drone-matrix template (#359) 2023-02-08 21:59:49 +01:00
renovate[bot]
d64945a83f
chore(deps): lock file maintenance (#352) 2023-02-08 10:03:25 +01:00
renovate[bot]
c48f71c99f chore(docker): update python:3.11-alpine docker digest to d8b0703 2023-02-04 12:29:38 +00:00
renovate[bot]
58440d6d59
fix(deps): update dependency prometheus-client to v0.16.0 (#356) 2023-02-02 09:08:27 +01:00
renovate[bot]
caf3e3826d chore(deps): update dependency flake8-docstrings to v1.7.0 2023-01-30 05:43:16 +00:00
renovate[bot]
d106aafb4f chore(docker): update python:3.11-alpine docker digest to ca1298a 2023-01-24 10:57:21 +00:00
renovate[bot]
60f67a82fb chore(deps): update dependency pydocstyle to v6.3.0 2023-01-23 05:12:49 +00:00
renovate[bot]
17486e82ee chore(docker): update python:3.11-alpine docker digest to 625383c 2023-01-18 16:35:50 +00:00
renovate[bot]
f0134ead55
fix(deps): update dependency requests to v2.28.2 (#349) 2023-01-16 09:33:39 +01:00
cb0bdb1166
refactor: use buildx for multiarch container builds (#350) 2023-01-16 09:10:43 +01:00
renovate[bot]
bf9ed4a050 chore(deps): update devdependencies (non-major) 2023-01-16 06:40:43 +00:00
renovate[bot]
4f217f0ef7 chore(docker): update docker digests 2023-01-10 11:20:52 +00:00
renovate[bot]
3fcae28ac9
chore(deps): lock file maintenance (#345) 2023-01-09 21:17:46 +01:00
renovate[bot]
17c4173748 chore(docker): update docker digests 2023-01-08 17:53:01 +00:00
250e4f0bf3
chore: remove support for arm32 (#347)
BREAKING CHANGE: We dropped the arm32 platform support and builds.
2023-01-08 16:12:34 +01:00
renovate[bot]
c4a28ac4b1
chore(deps): update dependency flake8-isort to v6 (#343) 2023-01-03 14:15:25 +01:00
renovate[bot]
effe4f1c13 chore(deps): update devdependencies (non-major) 2022-12-26 04:27:42 +00:00
renovate[bot]
01add1d430 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.37.1 2022-12-21 20:43:59 +00:00
renovate[bot]
29c87bfa11
chore(deps): lock file maintenance (#340) 2022-12-20 20:41:53 +01:00
renovate[bot]
25c5585f4b
fix(deps): update dependency proxmoxer to v2.0.1 (#341) 2022-12-20 20:40:10 +01:00
renovate[bot]
c107ee51ec chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.37.0 2022-12-12 01:10:37 +00:00
renovate[bot]
b9b984a2cb
chore(deps): lock file maintenance (#324) 2022-12-09 22:55:54 +01:00
renovate[bot]
7628cf9806
chore(docker): update docker digests (#338) 2022-12-09 22:55:42 +01:00
renovate[bot]
148c085271
fix(deps): update dependency proxmoxer to v2 (#335) 2022-12-04 19:05:57 +01:00
renovate[bot]
75ef2258b1
fix(deps): update dependency jsonschema to v4.17.3 (#336) 2022-12-04 18:21:02 +01:00
renovate[bot]
297eb78784 chore(docker): update docker digests 2022-11-30 06:41:06 +00:00
renovate[bot]
18a4a19379 chore(deps): update dependency flake8-logging-format to v0.9.0 2022-11-28 05:08:46 +00:00
763dd31053
ci: use python311 base image on ci (#333) 2022-11-24 21:35:49 +01:00
renovate[bot]
b8a97de4f9
fix(deps): update dependency jsonschema to v4.17.1 (#331) 2022-11-24 10:46:15 +01:00
renovate[bot]
503fe1452e chore(deps): update dependency flake8-isort to v5.0.3 2022-11-21 05:22:20 +00:00
renovate[bot]
834a6c13b2 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.36.1 2022-11-16 23:49:31 +00:00
renovate[bot]
65229ed8ca chore(docker): update docker digests 2022-11-16 17:35:29 +00:00
renovate[bot]
f28be49225 chore(docker): update docker digests 2022-11-12 14:28:19 +00:00
renovate[bot]
ca3dd6b390 chore(docker): update docker digests 2022-11-11 17:06:06 +00:00
renovate[bot]
1e9b2956e3 chore(docker): update docker digests 2022-11-11 06:51:40 +00:00
renovate[bot]
38874076d5 chore(deps): update dependency flake8-builtins to v2.0.1 2022-11-07 05:01:57 +00:00
3432149a5d
chore: bump hugo to v0.105.0 (#322) 2022-11-05 09:20:03 +01:00
c682b9aa4b
ci: refactor broken link check (#321) 2022-11-04 12:58:14 +01:00
renovate[bot]
9b607f7f84 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.36.0 2022-11-03 17:35:48 +00:00
1f964c5f5c
ci: add test step for python 11 (#319) 2022-11-02 13:01:49 +01:00
49 changed files with 1679 additions and 2576 deletions

View File

@ -1,23 +0,0 @@
# Changelog
{{ range .Versions -}}
## {{ if .Tag.Previous }}[{{ .Tag.Name }}]({{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}){{ else }}{{ .Tag.Name }}{{ end }} ({{ datetime "2006-01-02" .Tag.Date }})
{{ range .CommitGroups -}}
### {{ .Title }}
{{ range .Commits -}}
- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ (regexReplaceAll "(.*)/issues/(.*)" (regexReplaceAll "(Co-\\w*-by.*)" .Subject "") "${1}/pull/${2}") | trim }}
{{ end }}
{{- end -}}
{{- if .NoteGroups -}}
{{ range .NoteGroups -}}
### {{ .Title }}
{{ range .Notes }}
{{ .Body }}
{{ end }}
{{ end -}}
{{ end -}}
{{ end -}}

View File

@ -1,25 +0,0 @@
style: github
template: CHANGELOG.tpl.md
info:
title: CHANGELOG
repository_url: https://github.com/thegeeklab/prometheus-pve-sd
options:
commit_groups:
title_maps:
feat: Features
fix: Bug Fixes
perf: Performance Improvements
refactor: Code Refactoring
chore: Others
test: Testing
ci: CI Pipeline
docs: Documentation
header:
pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$"
pattern_maps:
- Type
- Scope
- Subject
notes:
keywords:
- BREAKING CHANGE

View File

@ -1,510 +0,0 @@
local PythonVersion(pyversion='3.7') = {
name: 'python' + std.strReplace(pyversion, '.', '') + '-pytest',
image: 'python:' + pyversion,
environment: {
PY_COLORS: 1,
},
commands: [
'pip install poetry poetry-dynamic-versioning -qq',
'poetry config experimental.new-installer false',
'poetry install',
'poetry run pytest --cov-append',
'poetry version',
'poetry run prometheus-pve-sd --help',
],
depends_on: [
'fetch',
],
};
local PipelineLint = {
kind: 'pipeline',
name: 'lint',
platform: {
os: 'linux',
arch: 'amd64',
},
steps: [
{
name: 'yapf',
image: 'python:3.10',
environment: {
PY_COLORS: 1,
},
commands: [
'git fetch -tq',
'pip install poetry poetry-dynamic-versioning -qq',
'poetry config experimental.new-installer false',
'poetry install',
'poetry run yapf -dr ./prometheuspvesd',
],
},
{
name: 'flake8',
image: 'python:3.10',
environment: {
PY_COLORS: 1,
},
commands: [
'git fetch -tq',
'pip install poetry poetry-dynamic-versioning -qq',
'poetry config experimental.new-installer false',
'poetry install',
'poetry run flake8 ./prometheuspvesd',
],
},
],
trigger: {
ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'],
},
};
local PipelineTest = {
kind: 'pipeline',
name: 'test',
platform: {
os: 'linux',
arch: 'amd64',
},
steps: [
{
name: 'fetch',
image: 'python:3.10',
commands: [
'git fetch -tq',
],
},
PythonVersion(pyversion='3.7'),
PythonVersion(pyversion='3.8'),
PythonVersion(pyversion='3.9'),
PythonVersion(pyversion='3.10'),
{
name: 'codecov',
image: 'python:3.10',
environment: {
PY_COLORS: 1,
CODECOV_TOKEN: { from_secret: 'codecov_token' },
},
commands: [
'pip install codecov -qq',
'codecov --required -X gcov',
],
depends_on: [
'python37-pytest',
'python38-pytest',
'python39-pytest',
'python310-pytest',
],
},
],
depends_on: [
'lint',
],
trigger: {
ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'],
},
};
local PipelineSecurity = {
kind: 'pipeline',
name: 'security',
platform: {
os: 'linux',
arch: 'amd64',
},
steps: [
{
name: 'bandit',
image: 'python:3.10',
environment: {
PY_COLORS: 1,
},
commands: [
'git fetch -tq',
'pip install poetry poetry-dynamic-versioning -qq',
'poetry config experimental.new-installer false',
'poetry install',
'poetry run bandit -r ./prometheuspvesd -x ./prometheuspvesd/test',
],
},
],
depends_on: [
'test',
],
trigger: {
ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'],
},
};
local PipelineBuildPackage = {
kind: 'pipeline',
name: 'build-package',
platform: {
os: 'linux',
arch: 'amd64',
},
steps: [
{
name: 'build',
image: 'python:3.10',
commands: [
'git fetch -tq',
'pip install poetry poetry-dynamic-versioning -qq',
'poetry build',
],
},
{
name: 'checksum',
image: 'alpine',
commands: [
'cd dist/ && sha256sum * > ../sha256sum.txt',
],
},
{
name: 'changelog-generate',
image: 'thegeeklab/git-chglog',
commands: [
'git fetch -tq',
'git-chglog --no-color --no-emoji -o CHANGELOG.md ${DRONE_TAG:---next-tag unreleased unreleased}',
],
},
{
name: 'changelog-format',
image: 'thegeeklab/alpine-tools',
commands: [
'prettier CHANGELOG.md',
'prettier -w CHANGELOG.md',
],
},
{
name: 'publish-github',
image: 'plugins/github-release',
settings: {
overwrite: true,
api_key: { from_secret: 'github_token' },
files: ['dist/*', 'sha256sum.txt'],
title: '${DRONE_TAG}',
note: 'CHANGELOG.md',
},
when: {
ref: ['refs/tags/**'],
},
},
{
name: 'publish-pypi',
image: 'python:3.10',
commands: [
'git fetch -tq',
'pip install poetry poetry-dynamic-versioning -qq',
'poetry publish -n',
],
environment: {
POETRY_HTTP_BASIC_PYPI_USERNAME: { from_secret: 'pypi_username' },
POETRY_HTTP_BASIC_PYPI_PASSWORD: { from_secret: 'pypi_password' },
},
when: {
ref: ['refs/tags/**'],
},
},
],
depends_on: [
'security',
],
trigger: {
ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'],
},
};
local PipelineBuildContainer(arch='amd64') = {
local build = if arch == 'arm' then [{
name: 'build',
image: 'python:3.10-alpine',
commands: [
'apk add -Uq --no-cache build-base openssl-dev libffi-dev musl-dev python3-dev git cargo',
'git fetch -tq',
'pip install poetry poetry-dynamic-versioning -qq',
'poetry build',
],
environment: {
CARGO_NET_GIT_FETCH_WITH_CLI: true,
},
}] else [{
name: 'build',
image: 'python:3.10',
commands: [
'git fetch -tq',
'pip install poetry poetry-dynamic-versioning -qq',
'poetry build',
],
}],
kind: 'pipeline',
name: 'build-container-' + arch,
platform: {
os: 'linux',
arch: arch,
},
steps: build + [
{
name: 'dryrun',
image: 'thegeeklab/drone-docker:19',
settings: {
dry_run: true,
dockerfile: 'docker/Dockerfile.' + arch,
repo: 'thegeeklab/${DRONE_REPO_NAME}',
username: { from_secret: 'docker_username' },
password: { from_secret: 'docker_password' },
},
depends_on: ['build'],
when: {
ref: ['refs/pull/**'],
},
},
{
name: 'publish-dockerhub',
image: 'thegeeklab/drone-docker:19',
settings: {
auto_tag: true,
auto_tag_suffix: arch,
dockerfile: 'docker/Dockerfile.' + arch,
repo: 'thegeeklab/${DRONE_REPO_NAME}',
username: { from_secret: 'docker_username' },
password: { from_secret: 'docker_password' },
},
when: {
ref: ['refs/heads/main', 'refs/tags/**'],
},
depends_on: ['dryrun'],
},
{
name: 'publish-quay',
image: 'thegeeklab/drone-docker:19',
settings: {
auto_tag: true,
auto_tag_suffix: arch,
dockerfile: 'docker/Dockerfile.' + arch,
registry: 'quay.io',
repo: 'quay.io/thegeeklab/${DRONE_REPO_NAME}',
username: { from_secret: 'quay_username' },
password: { from_secret: 'quay_password' },
},
when: {
ref: ['refs/heads/main', 'refs/tags/**'],
},
depends_on: ['dryrun'],
},
],
depends_on: [
'security',
],
trigger: {
ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'],
},
};
local PipelineDocs = {
kind: 'pipeline',
name: 'docs',
platform: {
os: 'linux',
arch: 'amd64',
},
concurrency: {
limit: 1,
},
steps: [
{
name: 'assets',
image: 'thegeeklab/alpine-tools',
commands: [
'make doc',
],
},
{
name: 'markdownlint',
image: 'thegeeklab/markdownlint-cli',
commands: [
"markdownlint 'docs/content/**/*.md' 'README.md' 'CONTRIBUTING.md'",
],
},
{
name: 'spellcheck',
image: 'thegeeklab/alpine-tools',
commands: [
"spellchecker --files 'docs/content/**/*.md' 'README.md' -d .dictionary -p spell indefinite-article syntax-urls --no-suggestions",
],
environment: {
FORCE_COLOR: true,
NPM_CONFIG_LOGLEVEL: 'error',
},
},
{
name: 'testbuild',
image: 'thegeeklab/hugo:0.97.3',
commands: [
'hugo --panicOnWarning -s docs/ -b http://localhost:8000/',
],
},
{
name: 'link-validation',
image: 'thegeeklab/link-validator',
commands: [
'link-validator --nice --external --skip-file .linkcheckignore',
],
environment: {
LINK_VALIDATOR_BASE_DIR: 'docs/public',
},
},
{
name: 'build',
image: 'thegeeklab/hugo:0.97.3',
commands: [
'hugo --panicOnWarning -s docs/',
],
},
{
name: 'beautify',
image: 'thegeeklab/alpine-tools',
commands: [
"html-beautify -r -f 'docs/public/**/*.html'",
],
environment: {
FORCE_COLOR: true,
NPM_CONFIG_LOGLEVEL: 'error',
},
},
{
name: 'publish',
image: 'thegeeklab/drone-s3-sync',
settings: {
access_key: { from_secret: 's3_access_key' },
bucket: 'geekdocs',
delete: true,
endpoint: 'https://sp.rknet.org',
path_style: true,
secret_key: { from_secret: 's3_secret_access_key' },
source: 'docs/public/',
strip_prefix: 'docs/public/',
target: '/${DRONE_REPO_NAME}',
},
when: {
ref: ['refs/heads/main', 'refs/tags/**'],
},
},
],
depends_on: [
'build-package',
'build-container-amd64',
'build-container-arm64',
'build-container-arm',
],
trigger: {
ref: ['refs/heads/main', 'refs/tags/**', 'refs/pull/**'],
},
};
local PipelineNotifications = {
kind: 'pipeline',
name: 'notifications',
platform: {
os: 'linux',
arch: 'amd64',
},
steps: [
{
image: 'plugins/manifest',
name: 'manifest-dockerhub',
settings: {
ignore_missing: true,
auto_tag: true,
username: { from_secret: 'docker_username' },
password: { from_secret: 'docker_password' },
spec: 'docker/manifest.tmpl',
},
when: {
status: ['success'],
},
},
{
image: 'plugins/manifest',
name: 'manifest-quay',
settings: {
ignore_missing: true,
auto_tag: true,
username: { from_secret: 'quay_username' },
password: { from_secret: 'quay_password' },
spec: 'docker/manifest-quay.tmpl',
},
when: {
status: ['success'],
},
},
{
name: 'pushrm-dockerhub',
pull: 'always',
image: 'chko/docker-pushrm:1',
environment: {
DOCKER_PASS: {
from_secret: 'docker_password',
},
DOCKER_USER: {
from_secret: 'docker_username',
},
PUSHRM_FILE: 'README.md',
PUSHRM_SHORT: 'Prometheus Service Discovery for Proxmox VE',
PUSHRM_TARGET: 'thegeeklab/${DRONE_REPO_NAME}',
},
when: {
status: ['success'],
},
},
{
name: 'pushrm-quay',
pull: 'always',
image: 'chko/docker-pushrm:1',
environment: {
APIKEY__QUAY_IO: {
from_secret: 'quay_token',
},
PUSHRM_FILE: 'README.md',
PUSHRM_TARGET: 'quay.io/thegeeklab/${DRONE_REPO_NAME}',
},
when: {
status: ['success'],
},
},
{
name: 'matrix',
image: 'thegeeklab/drone-matrix',
settings: {
homeserver: { from_secret: 'matrix_homeserver' },
roomid: { from_secret: 'matrix_roomid' },
template: 'Status: **{{ build.Status }}**<br/> Build: [{{ repo.Owner }}/{{ repo.Name }}]({{ build.Link }}){{#if build.Branch}} ({{ build.Branch }}){{/if}} by {{ commit.Author }}<br/> Message: {{ commit.Message.Title }}',
username: { from_secret: 'matrix_username' },
password: { from_secret: 'matrix_password' },
},
when: {
status: ['success', 'failure'],
},
},
],
depends_on: [
'docs',
],
trigger: {
ref: ['refs/heads/main', 'refs/tags/**'],
status: ['success', 'failure'],
},
};
[
PipelineLint,
PipelineTest,
PipelineSecurity,
PipelineBuildPackage,
PipelineBuildContainer(arch='amd64'),
PipelineBuildContainer(arch='arm64'),
PipelineBuildContainer(arch='arm'),
PipelineDocs,
PipelineNotifications,
]

View File

@ -1,652 +0,0 @@
---
kind: pipeline
name: lint
platform:
os: linux
arch: amd64
steps:
- name: yapf
image: python:3.10
commands:
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry config experimental.new-installer false
- poetry install
- poetry run yapf -dr ./prometheuspvesd
environment:
PY_COLORS: 1
- name: flake8
image: python:3.10
commands:
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry config experimental.new-installer false
- poetry install
- poetry run flake8 ./prometheuspvesd
environment:
PY_COLORS: 1
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
---
kind: pipeline
name: test
platform:
os: linux
arch: amd64
steps:
- name: fetch
image: python:3.10
commands:
- git fetch -tq
- name: python37-pytest
image: python:3.7
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry config experimental.new-installer false
- poetry install
- poetry run pytest --cov-append
- poetry version
- poetry run prometheus-pve-sd --help
environment:
PY_COLORS: 1
depends_on:
- fetch
- name: python38-pytest
image: python:3.8
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry config experimental.new-installer false
- poetry install
- poetry run pytest --cov-append
- poetry version
- poetry run prometheus-pve-sd --help
environment:
PY_COLORS: 1
depends_on:
- fetch
- name: python39-pytest
image: python:3.9
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry config experimental.new-installer false
- poetry install
- poetry run pytest --cov-append
- poetry version
- poetry run prometheus-pve-sd --help
environment:
PY_COLORS: 1
depends_on:
- fetch
- name: python310-pytest
image: python:3.10
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry config experimental.new-installer false
- poetry install
- poetry run pytest --cov-append
- poetry version
- poetry run prometheus-pve-sd --help
environment:
PY_COLORS: 1
depends_on:
- fetch
- name: codecov
image: python:3.10
commands:
- pip install codecov -qq
- codecov --required -X gcov
environment:
CODECOV_TOKEN:
from_secret: codecov_token
PY_COLORS: 1
depends_on:
- python37-pytest
- python38-pytest
- python39-pytest
- python310-pytest
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- lint
---
kind: pipeline
name: security
platform:
os: linux
arch: amd64
steps:
- name: bandit
image: python:3.10
commands:
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry config experimental.new-installer false
- poetry install
- poetry run bandit -r ./prometheuspvesd -x ./prometheuspvesd/test
environment:
PY_COLORS: 1
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- test
---
kind: pipeline
name: build-package
platform:
os: linux
arch: amd64
steps:
- name: build
image: python:3.10
commands:
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry build
- name: checksum
image: alpine
commands:
- cd dist/ && sha256sum * > ../sha256sum.txt
- name: changelog-generate
image: thegeeklab/git-chglog
commands:
- git fetch -tq
- git-chglog --no-color --no-emoji -o CHANGELOG.md ${DRONE_TAG:---next-tag unreleased unreleased}
- name: changelog-format
image: thegeeklab/alpine-tools
commands:
- prettier CHANGELOG.md
- prettier -w CHANGELOG.md
- name: publish-github
image: plugins/github-release
settings:
api_key:
from_secret: github_token
files:
- dist/*
- sha256sum.txt
note: CHANGELOG.md
overwrite: true
title: ${DRONE_TAG}
when:
ref:
- refs/tags/**
- name: publish-pypi
image: python:3.10
commands:
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry publish -n
environment:
POETRY_HTTP_BASIC_PYPI_PASSWORD:
from_secret: pypi_password
POETRY_HTTP_BASIC_PYPI_USERNAME:
from_secret: pypi_username
when:
ref:
- refs/tags/**
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- security
---
kind: pipeline
name: build-container-amd64
platform:
os: linux
arch: amd64
steps:
- name: build
image: python:3.10
commands:
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry build
- name: dryrun
image: thegeeklab/drone-docker:19
settings:
dockerfile: docker/Dockerfile.amd64
dry_run: true
password:
from_secret: docker_password
repo: thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: docker_username
when:
ref:
- refs/pull/**
depends_on:
- build
- name: publish-dockerhub
image: thegeeklab/drone-docker:19
settings:
auto_tag: true
auto_tag_suffix: amd64
dockerfile: docker/Dockerfile.amd64
password:
from_secret: docker_password
repo: thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: docker_username
when:
ref:
- refs/heads/main
- refs/tags/**
depends_on:
- dryrun
- name: publish-quay
image: thegeeklab/drone-docker:19
settings:
auto_tag: true
auto_tag_suffix: amd64
dockerfile: docker/Dockerfile.amd64
password:
from_secret: quay_password
registry: quay.io
repo: quay.io/thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: quay_username
when:
ref:
- refs/heads/main
- refs/tags/**
depends_on:
- dryrun
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- security
---
kind: pipeline
name: build-container-arm64
platform:
os: linux
arch: arm64
steps:
- name: build
image: python:3.10
commands:
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry build
- name: dryrun
image: thegeeklab/drone-docker:19
settings:
dockerfile: docker/Dockerfile.arm64
dry_run: true
password:
from_secret: docker_password
repo: thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: docker_username
when:
ref:
- refs/pull/**
depends_on:
- build
- name: publish-dockerhub
image: thegeeklab/drone-docker:19
settings:
auto_tag: true
auto_tag_suffix: arm64
dockerfile: docker/Dockerfile.arm64
password:
from_secret: docker_password
repo: thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: docker_username
when:
ref:
- refs/heads/main
- refs/tags/**
depends_on:
- dryrun
- name: publish-quay
image: thegeeklab/drone-docker:19
settings:
auto_tag: true
auto_tag_suffix: arm64
dockerfile: docker/Dockerfile.arm64
password:
from_secret: quay_password
registry: quay.io
repo: quay.io/thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: quay_username
when:
ref:
- refs/heads/main
- refs/tags/**
depends_on:
- dryrun
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- security
---
kind: pipeline
name: build-container-arm
platform:
os: linux
arch: arm
steps:
- name: build
image: python:3.10-alpine
commands:
- apk add -Uq --no-cache build-base openssl-dev libffi-dev musl-dev python3-dev git cargo
- git fetch -tq
- pip install poetry poetry-dynamic-versioning -qq
- poetry build
environment:
CARGO_NET_GIT_FETCH_WITH_CLI: true
- name: dryrun
image: thegeeklab/drone-docker:19
settings:
dockerfile: docker/Dockerfile.arm
dry_run: true
password:
from_secret: docker_password
repo: thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: docker_username
when:
ref:
- refs/pull/**
depends_on:
- build
- name: publish-dockerhub
image: thegeeklab/drone-docker:19
settings:
auto_tag: true
auto_tag_suffix: arm
dockerfile: docker/Dockerfile.arm
password:
from_secret: docker_password
repo: thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: docker_username
when:
ref:
- refs/heads/main
- refs/tags/**
depends_on:
- dryrun
- name: publish-quay
image: thegeeklab/drone-docker:19
settings:
auto_tag: true
auto_tag_suffix: arm
dockerfile: docker/Dockerfile.arm
password:
from_secret: quay_password
registry: quay.io
repo: quay.io/thegeeklab/${DRONE_REPO_NAME}
username:
from_secret: quay_username
when:
ref:
- refs/heads/main
- refs/tags/**
depends_on:
- dryrun
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- security
---
kind: pipeline
name: docs
platform:
os: linux
arch: amd64
concurrency:
limit: 1
steps:
- name: assets
image: thegeeklab/alpine-tools
commands:
- make doc
- name: markdownlint
image: thegeeklab/markdownlint-cli
commands:
- markdownlint 'docs/content/**/*.md' 'README.md' 'CONTRIBUTING.md'
- name: spellcheck
image: thegeeklab/alpine-tools
commands:
- spellchecker --files 'docs/content/**/*.md' 'README.md' -d .dictionary -p spell indefinite-article syntax-urls --no-suggestions
environment:
FORCE_COLOR: true
NPM_CONFIG_LOGLEVEL: error
- name: testbuild
image: thegeeklab/hugo:0.97.3
commands:
- hugo --panicOnWarning -s docs/ -b http://localhost:8000/
- name: link-validation
image: thegeeklab/link-validator
commands:
- link-validator --nice --external --skip-file .linkcheckignore
environment:
LINK_VALIDATOR_BASE_DIR: docs/public
- name: build
image: thegeeklab/hugo:0.97.3
commands:
- hugo --panicOnWarning -s docs/
- name: beautify
image: thegeeklab/alpine-tools
commands:
- html-beautify -r -f 'docs/public/**/*.html'
environment:
FORCE_COLOR: true
NPM_CONFIG_LOGLEVEL: error
- name: publish
image: thegeeklab/drone-s3-sync
settings:
access_key:
from_secret: s3_access_key
bucket: geekdocs
delete: true
endpoint: https://sp.rknet.org
path_style: true
secret_key:
from_secret: s3_secret_access_key
source: docs/public/
strip_prefix: docs/public/
target: /${DRONE_REPO_NAME}
when:
ref:
- refs/heads/main
- refs/tags/**
trigger:
ref:
- refs/heads/main
- refs/tags/**
- refs/pull/**
depends_on:
- build-package
- build-container-amd64
- build-container-arm64
- build-container-arm
---
kind: pipeline
name: notifications
platform:
os: linux
arch: amd64
steps:
- name: manifest-dockerhub
image: plugins/manifest
settings:
auto_tag: true
ignore_missing: true
password:
from_secret: docker_password
spec: docker/manifest.tmpl
username:
from_secret: docker_username
when:
status:
- success
- name: manifest-quay
image: plugins/manifest
settings:
auto_tag: true
ignore_missing: true
password:
from_secret: quay_password
spec: docker/manifest-quay.tmpl
username:
from_secret: quay_username
when:
status:
- success
- name: pushrm-dockerhub
pull: always
image: chko/docker-pushrm:1
environment:
DOCKER_PASS:
from_secret: docker_password
DOCKER_USER:
from_secret: docker_username
PUSHRM_FILE: README.md
PUSHRM_SHORT: Prometheus Service Discovery for Proxmox VE
PUSHRM_TARGET: thegeeklab/${DRONE_REPO_NAME}
when:
status:
- success
- name: pushrm-quay
pull: always
image: chko/docker-pushrm:1
environment:
APIKEY__QUAY_IO:
from_secret: quay_token
PUSHRM_FILE: README.md
PUSHRM_TARGET: quay.io/thegeeklab/${DRONE_REPO_NAME}
when:
status:
- success
- name: matrix
image: thegeeklab/drone-matrix
settings:
homeserver:
from_secret: matrix_homeserver
password:
from_secret: matrix_password
roomid:
from_secret: matrix_roomid
template: "Status: **{{ build.Status }}**<br/> Build: [{{ repo.Owner }}/{{ repo.Name }}]({{ build.Link }}){{#if build.Branch}} ({{ build.Branch }}){{/if}} by {{ commit.Author }}<br/> Message: {{ commit.Message.Title }}"
username:
from_secret: matrix_username
when:
status:
- success
- failure
trigger:
ref:
- refs/heads/main
- refs/tags/**
status:
- success
- failure
depends_on:
- docs
---
kind: signature
hmac: fb17f8e878e4a97dc5654eb0a32d3b23b5154a5b7d1d499997d7dd4f1d827880
...

View File

@ -52,7 +52,11 @@ branches:
required_status_checks: required_status_checks:
strict: false strict: false
contexts: contexts:
- continuous-integration/drone/pr - ci/woodpecker/pr/lint
enforce_admins: true - ci/woodpecker/pr/test
- ci/woodpecker/pr/build-package
- ci/woodpecker/pr/build-container
- ci/woodpecker/pr/docs
enforce_admins: false
required_linear_history: true required_linear_history: true
restrictions: null restrictions: null

1
.gitignore vendored
View File

@ -110,3 +110,4 @@ resources/_gen/
# Misc # Misc
CHANGELOG.md CHANGELOG.md
.ruff_cache

47
.gitsv/config.yml Normal file
View File

@ -0,0 +1,47 @@
---
version: "1.1"
versioning:
update-major: []
update-minor: [feat]
update-patch: [fix, perf, refactor, chore, test, ci, docs]
tag:
pattern: "v%d.%d.%d"
release-notes:
sections:
- name: Features
commit-types: [feat]
section-type: commits
- name: Bug Fixes
commit-types: [fix]
section-type: commits
- name: Performance Improvements
commit-types: [perf]
section-type: commits
- name: Code Refactoring
commit-types: [refactor]
section-type: commits
- name: Others
commit-types: [chore]
section-type: commits
- name: Testing
commit-types: [test]
section-type: commits
- name: CI Pipeline
commit-types: [ci]
section-type: commits
- name: Documentation
commit-types: [docs]
section-type: commits
- name: Breaking Changes
section-type: breaking-changes
commit-message:
footer:
issue:
key: issue
add-value-prefix: "#"
issue:
regex: "#?[0-9]+"

1
.lycheeignore Normal file
View File

@ -0,0 +1 @@
https://hub.docker.com/r/thegeeklab/*

View File

@ -1,3 +1,2 @@
.drone.yml
*.tpl.md *.tpl.md
LICENSE LICENSE

View File

@ -0,0 +1,84 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
- name: build
image: docker.io/library/python:3.13
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry build
- name: security-build
image: quay.io/thegeeklab/wp-docker-buildx:5
depends_on: [build]
settings:
containerfile: Containerfile.multiarch
output: type=oci,dest=oci/${CI_REPO_NAME},tar=false
repo: ${CI_REPO}
registry_config:
from_secret: DOCKER_REGISTRY_CONFIG_PULL
- name: security-scan
image: docker.io/aquasec/trivy
depends_on: [security-build]
commands:
- trivy -v
- trivy image --input oci/${CI_REPO_NAME}
environment:
TRIVY_EXIT_CODE: "1"
TRIVY_IGNORE_UNFIXED: "true"
TRIVY_NO_PROGRESS: "true"
TRIVY_SEVERITY: HIGH,CRITICAL
TRIVY_TIMEOUT: 1m
TRIVY_DB_REPOSITORY: docker.io/aquasec/trivy-db:2
- name: publish-dockerhub
image: quay.io/thegeeklab/wp-docker-buildx:5
depends_on: [security-scan]
settings:
auto_tag: true
containerfile: Containerfile.multiarch
password:
from_secret: docker_password
platforms:
- linux/amd64
- linux/arm64
provenance: false
repo: ${CI_REPO}
username:
from_secret: docker_username
when:
- event: [tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
- name: publish-quay
image: quay.io/thegeeklab/wp-docker-buildx:5
depends_on: security-scan
settings:
auto_tag: true
containerfile: Containerfile.multiarch
password:
from_secret: quay_password
platforms:
- linux/amd64
- linux/arm64
provenance: false
registry: quay.io
repo: quay.io/${CI_REPO}
username:
from_secret: quay_username
when:
- event: [tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
depends_on:
- lint
- test

View File

@ -0,0 +1,56 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
- name: build
image: docker.io/library/python:3.13
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry build
- name: checksum
image: quay.io/thegeeklab/alpine-tools
commands:
- cd dist/ && sha256sum * > ../sha256sum.txt
- name: changelog
image: quay.io/thegeeklab/git-sv
commands:
- git sv current-version
- git sv release-notes -t ${CI_COMMIT_TAG:-next} -o CHANGELOG.md
- cat CHANGELOG.md
- name: publish-github
image: docker.io/plugins/github-release
settings:
api_key:
from_secret: github_token
files:
- dist/*
- sha256sum.txt
note: CHANGELOG.md
overwrite: true
title: ${CI_COMMIT_TAG}
when:
- event: [tag]
- name: publish-pypi
image: docker.io/library/python:3.13
environment:
POETRY_HTTP_BASIC_PYPI_PASSWORD:
from_secret: pypi_password
POETRY_HTTP_BASIC_PYPI_USERNAME:
from_secret: pypi_username
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry publish -n
when:
- event: [tag]
depends_on:
- lint
- test

101
.woodpecker/docs.yml Normal file
View File

@ -0,0 +1,101 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
- name: assets
image: quay.io/thegeeklab/alpine-tools
commands:
- make doc
- name: markdownlint
image: quay.io/thegeeklab/markdownlint-cli
depends_on: [assets]
commands:
- markdownlint 'README.md' 'CONTRIBUTING.md'
- name: spellcheck
image: quay.io/thegeeklab/alpine-tools
depends_on: [assets]
commands:
- spellchecker --files 'docs/**/*.md' 'README.md' 'CONTRIBUTING.md' -d .dictionary -p spell indefinite-article syntax-urls
environment:
FORCE_COLOR: "true"
- name: link-validation
image: docker.io/lycheeverse/lychee
depends_on: [assets]
commands:
- lychee --no-progress --format detailed docs/content README.md
- name: build
image: quay.io/thegeeklab/hugo:0.136.5
depends_on: [link-validation]
commands:
- hugo --panicOnWarning -s docs/
- name: beautify
image: quay.io/thegeeklab/alpine-tools
depends_on: [build]
commands:
- html-beautify -r -f 'docs/public/**/*.html'
- name: publish
image: quay.io/thegeeklab/wp-s3-action
depends_on: [beautify]
settings:
access_key:
from_secret: s3_access_key
bucket: geekdocs
delete: true
endpoint:
from_secret: s3_endpoint
path_style: true
secret_key:
from_secret: s3_secret_access_key
source: docs/public/
strip_prefix: docs/public/
target: /${CI_REPO_NAME}
when:
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
status: [success, failure]
- name: pushrm-dockerhub
image: docker.io/chko/docker-pushrm:1
depends_on: [publish]
environment:
DOCKER_PASS:
from_secret: docker_password
DOCKER_USER:
from_secret: docker_username
PUSHRM_FILE: README.md
PUSHRM_SHORT: Prometheus Service Discovery for Proxmox VE
PUSHRM_TARGET: ${CI_REPO}
when:
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
status: [success]
- name: pushrm-quay
image: docker.io/chko/docker-pushrm:1
depends_on: [publish]
environment:
APIKEY__QUAY_IO:
from_secret: quay_token
PUSHRM_FILE: README.md
PUSHRM_TARGET: quay.io/${CI_REPO}
when:
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
status: [success]
depends_on:
- build-package
- build-container

27
.woodpecker/lint.yml Normal file
View File

@ -0,0 +1,27 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
- name: check-format
image: docker.io/library/python:3.13
depends_on: []
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry install
- poetry run ruff format --check --diff ./${CI_REPO_NAME//-/}
environment:
PY_COLORS: "1"
- name: check-coding
image: docker.io/library/python:3.13
depends_on: []
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry install
- poetry run ruff check ./${CI_REPO_NAME//-/}
environment:
PY_COLORS: "1"

26
.woodpecker/notify.yml Normal file
View File

@ -0,0 +1,26 @@
---
when:
- event: [tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
runs_on: [success, failure]
steps:
- name: matrix
image: quay.io/thegeeklab/wp-matrix
settings:
homeserver:
from_secret: matrix_homeserver
room_id:
from_secret: matrix_room_id
user_id:
from_secret: matrix_user_id
access_token:
from_secret: matrix_access_token
when:
- status: [success, failure]
depends_on:
- docs

35
.woodpecker/test.yml Normal file
View File

@ -0,0 +1,35 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
variables:
- &pytest_base
depends_on: []
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry install
- poetry run pytest --cov-append
- poetry version
- poetry run ${CI_REPO_NAME} --help
environment:
PY_COLORS: "1"
steps:
- name: python-313
image: docker.io/library/python:3.13
<<: *pytest_base
- name: python-312
image: docker.io/library/python:3.12
<<: *pytest_base
- name: python-311
image: docker.io/library/python:3.11
<<: *pytest_base
- name: python-310
image: docker.io/library/python:3.10
<<: *pytest_base

View File

@ -3,7 +3,7 @@
## Security ## Security
If you think you have found a **security issue**, please do not mention it in this repository. If you think you have found a **security issue**, please do not mention it in this repository.
Instead, send an email to security@thegeeklab.de with as many details as possible so it can be handled confidential. Instead, send an email to `security@thegeeklab.de` with as many details as possible so it can be handled confidential.
## Bug Reports and Feature Requests ## Bug Reports and Feature Requests

View File

@ -1,4 +1,4 @@
FROM python:3.11-alpine@sha256:2a068b9442f61f4480306d44e3b166bfe3343761e9bd57c38f66302ebf28fd9e FROM python:3.13-alpine@sha256:fcbcbbecdeae71d3b77445d9144d1914df55110f825ab62b04a66c7c33c09373
LABEL maintainer="Robert Kaussow <mail@thegeeklab.de>" LABEL maintainer="Robert Kaussow <mail@thegeeklab.de>"
LABEL org.opencontainers.image.authors="Robert Kaussow <mail@thegeeklab.de>" LABEL org.opencontainers.image.authors="Robert Kaussow <mail@thegeeklab.de>"

View File

@ -1,5 +1,5 @@
# renovate: datasource=github-releases depName=thegeeklab/hugo-geekdoc # renovate: datasource=github-releases depName=thegeeklab/hugo-geekdoc
THEME_VERSION := v0.35.8 THEME_VERSION := v1.2.1
THEME := hugo-geekdoc THEME := hugo-geekdoc
BASEDIR := docs BASEDIR := docs
THEMEDIR := $(BASEDIR)/themes THEMEDIR := $(BASEDIR)/themes

View File

@ -2,13 +2,12 @@
Prometheus Service Discovery for Proxmox VE Prometheus Service Discovery for Proxmox VE
[![Build Status](https://img.shields.io/drone/build/thegeeklab/prometheus-pve-sd?logo=drone&server=https%3A%2F%2Fdrone.thegeeklab.de)](https://drone.thegeeklab.de/thegeeklab/prometheus-pve-sd) [![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/prometheus-pve-sd/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/prometheus-pve-sd)
[![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/prometheus-pve-sd) [![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/prometheus-pve-sd)
[![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/prometheus-pve-sd) [![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/prometheus-pve-sd)
[![Python Version](https://img.shields.io/pypi/pyversions/prometheus-pve-sd.svg)](https://pypi.org/project/prometheus-pve-sd/) [![Python Version](https://img.shields.io/pypi/pyversions/prometheus-pve-sd.svg)](https://pypi.org/project/prometheus-pve-sd/)
[![PyPI Status](https://img.shields.io/pypi/status/prometheus-pve-sd.svg)](https://pypi.org/project/prometheus-pve-sd/) [![PyPI Status](https://img.shields.io/pypi/status/prometheus-pve-sd.svg)](https://pypi.org/project/prometheus-pve-sd/)
[![PyPI Release](https://img.shields.io/pypi/v/prometheus-pve-sd.svg)](https://pypi.org/project/prometheus-pve-sd/) [![PyPI Release](https://img.shields.io/pypi/v/prometheus-pve-sd.svg)](https://pypi.org/project/prometheus-pve-sd/)
[![Codecov](https://img.shields.io/codecov/c/github/thegeeklab/prometheus-pve-sd)](https://codecov.io/gh/thegeeklab/prometheus-pve-sd)
[![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/prometheus-pve-sd)](https://github.com/thegeeklab/prometheus-pve-sd/graphs/contributors) [![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/prometheus-pve-sd)](https://github.com/thegeeklab/prometheus-pve-sd/graphs/contributors)
[![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/thegeeklab/prometheus-pve-sd) [![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/thegeeklab/prometheus-pve-sd)
[![License: MIT](https://img.shields.io/github/license/thegeeklab/prometheus-pve-sd)](https://github.com/thegeeklab/prometheus-pve-sd/blob/main/LICENSE) [![License: MIT](https://img.shields.io/github/license/thegeeklab/prometheus-pve-sd)](https://github.com/thegeeklab/prometheus-pve-sd/blob/main/LICENSE)

View File

@ -1,24 +0,0 @@
FROM arm32v7/python:3.11-alpine@sha256:ed2285150d39677d00da2a48c357b0e61153f35974819b267765519c70405e35
LABEL maintainer="Robert Kaussow <mail@thegeeklab.de>"
LABEL org.opencontainers.image.authors="Robert Kaussow <mail@thegeeklab.de>"
LABEL org.opencontainers.image.title="prometheus-pve-sd"
LABEL org.opencontainers.image.url="https://github.com/thegeeklab/prometheus-pve-sd/"
LABEL org.opencontainers.image.source="https://github.com/thegeeklab/prometheus-pve-sd/"
LABEL org.opencontainers.image.documentation="https://github.com/thegeeklab/prometheus-pve-sd/"
ENV PY_COLORS=1
ENV TZ=UTC
ADD dist/prometheus_pve_sd-*.whl /
RUN apk --update add --virtual .build-deps build-base libffi-dev openssl-dev && \
pip install --upgrade --no-cache-dir pip && \
pip install --no-cache-dir $(find / -name "prometheus_pve_sd-*.whl") && \
rm -f prometheus_pve_sd-*.whl && \
rm -rf /var/cache/apk/* && \
rm -rf /root/.cache/
USER root
CMD []
ENTRYPOINT ["/usr/local/bin/prometheus-pve-sd"]

View File

@ -1,24 +0,0 @@
FROM arm64v8/python:3.11-alpine@sha256:8b76406c45a3c49a6ce2d190c771aeb3695648bd07d2147e3ae8d00e2516aa2b
LABEL maintainer="Robert Kaussow <mail@thegeeklab.de>"
LABEL org.opencontainers.image.authors="Robert Kaussow <mail@thegeeklab.de>"
LABEL org.opencontainers.image.title="prometheus-pve-sd"
LABEL org.opencontainers.image.url="https://github.com/thegeeklab/prometheus-pve-sd/"
LABEL org.opencontainers.image.source="https://github.com/thegeeklab/prometheus-pve-sd/"
LABEL org.opencontainers.image.documentation="https://github.com/thegeeklab/prometheus-pve-sd/"
ENV PY_COLORS=1
ENV TZ=UTC
ADD dist/prometheus_pve_sd-*.whl /
RUN apk --update add --virtual .build-deps build-base libffi-dev openssl-dev && \
pip install --upgrade --no-cache-dir pip && \
pip install --no-cache-dir $(find / -name "prometheus_pve_sd-*.whl") && \
rm -f prometheus_pve_sd-*.whl && \
rm -rf /var/cache/apk/* && \
rm -rf /root/.cache/
USER root
CMD []
ENTRYPOINT ["/usr/local/bin/prometheus-pve-sd"]

View File

@ -1,24 +0,0 @@
image: quay.io/thegeeklab/prometheus-pve-sd:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}}
{{#if build.tags}}
tags:
{{#each build.tags}}
- {{this}}
{{/each}}
{{/if}}
manifests:
- image: quay.io/thegeeklab/prometheus-pve-sd:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}amd64
platform:
architecture: amd64
os: linux
- image: quay.io/thegeeklab/prometheus-pve-sd:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm64
platform:
architecture: arm64
os: linux
variant: v8
- image: quay.io/thegeeklab/prometheus-pve-sd:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm
platform:
architecture: arm
os: linux
variant: v7

View File

@ -1,24 +0,0 @@
image: thegeeklab/prometheus-pve-sd:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}}
{{#if build.tags}}
tags:
{{#each build.tags}}
- {{this}}
{{/each}}
{{/if}}
manifests:
- image: thegeeklab/prometheus-pve-sd:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}amd64
platform:
architecture: amd64
os: linux
- image: thegeeklab/prometheus-pve-sd:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm64
platform:
architecture: arm64
os: linux
variant: v8
- image: thegeeklab/prometheus-pve-sd:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm
platform:
architecture: arm
os: linux
variant: v7

View File

@ -2,13 +2,12 @@
title: Documentation title: Documentation
--- ---
[![Build Status](https://img.shields.io/drone/build/thegeeklab/prometheus-pve-sd?logo=drone&server=https%3A%2F%2Fdrone.thegeeklab.de)](https://drone.thegeeklab.de/thegeeklab/prometheus-pve-sd) [![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/prometheus-pve-sd/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/prometheus-pve-sd)
[![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/prometheus-pve-sd) [![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/prometheus-pve-sd)
[![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/prometheus-pve-sd) [![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/prometheus-pve-sd)
[![Python Version](https://img.shields.io/pypi/pyversions/prometheus-pve-sd.svg)](https://pypi.org/project/prometheus-pve-sd/) [![Python Version](https://img.shields.io/pypi/pyversions/prometheus-pve-sd.svg)](https://pypi.org/project/prometheus-pve-sd/)
[![PyPI Status](https://img.shields.io/pypi/status/prometheus-pve-sd.svg)](https://pypi.org/project/prometheus-pve-sd/) [![PyPI Status](https://img.shields.io/pypi/status/prometheus-pve-sd.svg)](https://pypi.org/project/prometheus-pve-sd/)
[![PyPI Release](https://img.shields.io/pypi/v/prometheus-pve-sd.svg)](https://pypi.org/project/prometheus-pve-sd/) [![PyPI Release](https://img.shields.io/pypi/v/prometheus-pve-sd.svg)](https://pypi.org/project/prometheus-pve-sd/)
[![Codecov](https://img.shields.io/codecov/c/github/thegeeklab/prometheus-pve-sd)](https://codecov.io/gh/thegeeklab/prometheus-pve-sd)
[![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/prometheus-pve-sd)](https://github.com/thegeeklab/prometheus-pve-sd/graphs/contributors) [![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/prometheus-pve-sd)](https://github.com/thegeeklab/prometheus-pve-sd/graphs/contributors)
[![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/thegeeklab/prometheus-pve-sd) [![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/thegeeklab/prometheus-pve-sd)
[![License: MIT](https://img.shields.io/github/license/thegeeklab/prometheus-pve-sd)](https://github.com/thegeeklab/prometheus-pve-sd/blob/main/LICENSE) [![License: MIT](https://img.shields.io/github/license/thegeeklab/prometheus-pve-sd)](https://github.com/thegeeklab/prometheus-pve-sd/blob/main/LICENSE)

View File

@ -35,18 +35,30 @@ include_vmid: []
exclude_tags: [] exclude_tags: []
include_tags: [] include_tags: []
# Set either password or token_name and token_value
pve: pve:
server: server:
user: user:
password: password:
token_name:
token_value:
auth_timeout: 5 auth_timeout: 5
verify_ssl: true verify_ssl: true
# Example # Example with password
# pve: # pve:
# server: proxmox.example.com # server: proxmox.example.com
# user: root # user: root
# password: secure # password: secure
# auth_timeout: 5 # auth_timeout: 5
# verify_ssl: true # verify_ssl: true
# Example with API token
# pve:
# server: proxmox.example.com
# user: root
# token_name: pve_sd
# token_value: 01234567-89ab-cdef-0123-456789abcdef
# auth_timeout: 5
# verify_ssl: true
``` ```

View File

@ -36,6 +36,8 @@ PROMETHEUS_PVE_SD_INCLUDE_TAGS=
PROMETHEUS_PVE_SD_PVE_SERVER= PROMETHEUS_PVE_SD_PVE_SERVER=
PROMETHEUS_PVE_SD_PVE_USER= PROMETHEUS_PVE_SD_PVE_USER=
PROMETHEUS_PVE_SD_PVE_PASSWORD= PROMETHEUS_PVE_SD_PVE_PASSWORD=
PROMETHEUS_PVE_SD_PVE_TOKEN_NAME=
PROMETHEUS_PVE_SD_PVE_TOKEN_VALUE=
PROMETHEUS_PVE_SD_PVE_AUTH_TIMEOUT=5 PROMETHEUS_PVE_SD_PVE_AUTH_TIMEOUT=5
PROMETHEUS_PVE_SD_PVE_VERIFY_SSL=true PROMETHEUS_PVE_SD_PVE_VERIFY_SSL=true
``` ```

162
docs/static/socialmedia.svg vendored Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 32 KiB

1465
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

View File

@ -37,11 +37,9 @@ class PrometheusSD:
self.discovery = Discovery() self.discovery = Discovery()
except APIError as e: except APIError as e:
if not self.config.config["service"]: if not self.config.config["service"]:
self.log.sysexit_with_message( self.log.sysexit_with_message(f"Proxmoxer API error: {str(e).strip()}")
"Proxmoxer API error: {0}".format(str(e).strip())
)
self.logger.error("Proxmoxer API error: {0}".format(str(e).strip())) self.logger.error(f"Proxmoxer API error: {str(e).strip()}")
sleep(60) sleep(60)
continue continue
else: else:
@ -61,7 +59,7 @@ class PrometheusSD:
"--config", "--config",
dest="config_file", dest="config_file",
action="store", action="store",
help="location of configuration file" help="location of configuration file",
) )
parser.add_argument( parser.add_argument(
"-o", "--output", dest="output_file", action="store", help="output file" "-o", "--output", dest="output_file", action="store", help="output file"
@ -75,14 +73,14 @@ class PrometheusSD:
dest="loop_delay", dest="loop_delay",
action="store", action="store",
type=int, type=int,
help="delay between discovery runs" help="delay between discovery runs",
) )
parser.add_argument( parser.add_argument(
"--no-service", "--no-service",
dest="service", dest="service",
action="store_false", action="store_false",
default=None, default=None,
help="run discovery only once" help="run discovery only once",
) )
parser.add_argument( parser.add_argument(
"-f", "-f",
@ -90,7 +88,7 @@ class PrometheusSD:
dest="logging.format", dest="logging.format",
metavar="LOG_FORMAT", metavar="LOG_FORMAT",
action="store", action="store",
help="used log format" help="used log format",
) )
parser.add_argument( parser.add_argument(
"-v", dest="logging.level", action="append_const", const=-1, help="increase log level" "-v", dest="logging.level", action="append_const", const=-1, help="increase log level"
@ -98,9 +96,7 @@ class PrometheusSD:
parser.add_argument( parser.add_argument(
"-q", dest="logging.level", action="append_const", const=1, help="decrease log level" "-q", dest="logging.level", action="append_const", const=1, help="decrease log level"
) )
parser.add_argument( parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
"--version", action="version", version="%(prog)s {}".format(__version__)
)
return parser.parse_args().__dict__ return parser.parse_args().__dict__
@ -115,16 +111,25 @@ class PrometheusSD:
config.config["logging"]["level"], config.config["logging"]["format"] config.config["logging"]["level"], config.config["logging"]["format"]
) )
except ValueError as e: except ValueError as e:
self.log.sysexit_with_message("Can not set log level.\n{}".format(str(e))) self.log.sysexit_with_message(f"Can not set log level.\n{e!s}")
required = [("pve.server", config.config["pve"]["server"]), required = [
("pve.user", config.config["pve"]["user"]), ("pve.server", config.config["pve"]["server"]),
("pve.password", config.config["pve"]["password"])] ("pve.user", config.config["pve"]["user"]),
]
for name, value in required: for name, value in required:
if not value: if not value:
self.log.sysexit_with_message("Option '{}' is required but not set".format(name)) self.log.sysexit_with_message(f"Option '{name}' is required but not set")
self.logger.info("Using config file {}".format(config.config_file)) if not config.config["pve"]["password"] and not (
config.config["pve"]["token_name"] and config.config["pve"]["token_value"]
):
self.log.sysexit_with_message(
"Either 'pve.password' or 'pve.token_name' and 'pve.token_value' "
"are required but not set"
)
self.logger.info(f"Using config file {config.config_file}")
return config return config
@ -140,16 +145,16 @@ class PrometheusSD:
) )
start_http_server( start_http_server(
self.config.config["metrics"]["port"], self.config.config["metrics"]["port"],
addr=self.config.config["metrics"]["address"] addr=self.config.config["metrics"]["address"],
) )
while True: while True:
try: try:
inventory = self.discovery.propagate() inventory = self.discovery.propagate()
except APIError as e: except APIError as e:
self.logger.error("Proxmoxer API error: {0}".format(str(e).strip())) self.logger.error(f"Proxmoxer API error: {str(e).strip()}")
except Exception as e: # noqa except Exception as e: # noqa
self.logger.error("Unknown error: {0}".format(str(e).strip())) self.logger.error(f"Unknown error: {str(e).strip()}")
else: else:
self._write(inventory) self._write(inventory)
@ -169,14 +174,13 @@ class PrometheusSD:
output.append(host.to_sd_json()) output.append(host.to_sd_json())
# Write to tmp file and move after write # Write to tmp file and move after write
temp_file = tempfile.NamedTemporaryFile(mode="w", prefix="prometheus-pve-sd", delete=False) with tempfile.NamedTemporaryFile(mode="w", prefix="prometheus-pve-sd", delete=False) as tf:
with temp_file as tf:
json.dump(output, tf, indent=4) json.dump(output, tf, indent=4)
shutil.move(temp_file.name, self.config.config["output_file"]) shutil.move(tf.name, self.config.config["output_file"])
chmod(self.config.config["output_file"], int(self.config.config["output_file_mode"], 8)) chmod(self.config.config["output_file"], int(self.config.config["output_file_mode"], 8))
def _terminate(self, signal, frame): def _terminate(self, signal, frame): # noqa
self.log.sysexit_with_message("Terminating", code=0) self.log.sysexit_with_message("Terminating", code=0)

View File

@ -1,4 +1,5 @@
"""Proxmox Client.""" """Proxmox Client."""
import requests import requests
from prometheus_client import Counter from prometheus_client import Counter
@ -10,6 +11,7 @@ from prometheuspvesd.utils import to_bool
try: try:
from proxmoxer import ProxmoxAPI from proxmoxer import ProxmoxAPI
HAS_PROXMOXER = True HAS_PROXMOXER = True
except ImportError: except ImportError:
HAS_PROXMOXER = False HAS_PROXMOXER = False
@ -44,16 +46,28 @@ class ProxmoxClient:
self.config.config["pve"]["server"], self.config.config["pve"]["user"] self.config.config["pve"]["server"], self.config.config["pve"]["user"]
) )
) )
if self.config.config["pve"]["token_name"]:
self.logger.debug("Using token login")
return ProxmoxAPI(
self.config.config["pve"]["server"],
user=self.config.config["pve"]["user"],
token_name=self.config.config["pve"]["token_name"],
token_value=self.config.config["pve"]["token_value"],
verify_ssl=to_bool(self.config.config["pve"]["verify_ssl"]),
timeout=self.config.config["pve"]["auth_timeout"],
)
return ProxmoxAPI( return ProxmoxAPI(
self.config.config["pve"]["server"], self.config.config["pve"]["server"],
user=self.config.config["pve"]["user"], user=self.config.config["pve"]["user"],
password=self.config.config["pve"]["password"], password=self.config.config["pve"]["password"],
verify_ssl=to_bool(self.config.config["pve"]["verify_ssl"]), verify_ssl=to_bool(self.config.config["pve"]["verify_ssl"]),
timeout=self.config.config["pve"]["auth_timeout"] timeout=self.config.config["pve"]["auth_timeout"],
) )
except requests.RequestException as e: except requests.RequestException as e:
PVE_REQUEST_COUNT_ERROR_TOTAL.inc() PVE_REQUEST_COUNT_ERROR_TOTAL.inc()
raise APIError(str(e)) raise APIError(str(e)) from e
def _do_request(self, *args): def _do_request(self, *args):
PVE_REQUEST_COUNT_TOTAL.inc() PVE_REQUEST_COUNT_TOTAL.inc()
@ -62,29 +76,30 @@ class ProxmoxClient:
return self.client.get(*("nodes", *args)) return self.client.get(*("nodes", *args))
except requests.RequestException as e: except requests.RequestException as e:
PVE_REQUEST_COUNT_ERROR_TOTAL.inc() PVE_REQUEST_COUNT_ERROR_TOTAL.inc()
raise APIError(str(e)) raise APIError(str(e)) from e
def get_nodes(self): def get_nodes(self):
self.logger.debug("fetching all nodes") self.logger.debug("fetching all nodes")
return self._do_request() return self._do_request()
def get_all_vms(self, pve_node): def get_all_vms(self, pve_node):
self.logger.debug("fetching all vms on node {}".format(pve_node)) self.logger.debug(f"fetching all vms on node {pve_node}")
return self._do_request(pve_node, "qemu") return self._do_request(pve_node, "qemu")
def get_all_containers(self, pve_node): def get_all_containers(self, pve_node):
self.logger.debug("fetching all containers on node {}".format(pve_node)) self.logger.debug(f"fetching all containers on node {pve_node}")
return self._do_request(pve_node, "lxc") return self._do_request(pve_node, "lxc")
def get_instance_config(self, pve_node, pve_type, vmid): def get_instance_config(self, pve_node, pve_type, vmid):
self.logger.debug("fetching instance config for {} on {}".format(vmid, pve_node)) self.logger.debug(f"fetching instance config for {vmid} on {pve_node}")
return self._do_request(pve_node, pve_type, vmid, "config") return self._do_request(pve_node, pve_type, vmid, "config")
def get_agent_info(self, pve_node, pve_type, vmid): def get_agent_info(self, pve_node, pve_type, vmid):
self.logger.debug("fetching agent info for {} on {}".format(vmid, pve_node)) self.logger.debug(f"fetching agent info for {vmid} on {pve_node}")
return self._do_request(pve_node, pve_type, vmid, "agent", "info")["result"] return self._do_request(pve_node, pve_type, vmid, "agent", "info")["result"]
def get_network_interfaces(self, pve_node, vmid): def get_network_interfaces(self, pve_node, vmid):
self.logger.debug("fetching network interfaces for {} on {}".format(vmid, pve_node)) self.logger.debug(f"fetching network interfaces for {vmid} on {pve_node}")
return self._do_request(pve_node, "qemu", vmid, "agent", return self._do_request(pve_node, "qemu", vmid, "agent", "network-get-interfaces")[
"network-get-interfaces")["result"] "result"
]

View File

@ -2,8 +2,7 @@
"""Global settings definition.""" """Global settings definition."""
import os import os
from pathlib import Path from pathlib import Path, PurePath
from pathlib import PurePath
import anyconfig import anyconfig
import environs import environs
@ -21,7 +20,7 @@ cache_dir = AppDirs("prometheus-pve-sd").user_cache_dir
default_output_file = os.path.join(cache_dir, "pve.json") default_output_file = os.path.join(cache_dir, "pve.json")
class Config(): class Config:
""" """
Create an object with all necessary settings. Create an object with all necessary settings.
@ -35,122 +34,134 @@ class Config():
"metrics.enabled": { "metrics.enabled": {
"default": True, "default": True,
"env": "METRICS_ENABLED", "env": "METRICS_ENABLED",
"type": environs.Env().bool "type": environs.Env().bool,
}, },
"metrics.address": { "metrics.address": {
"default": "127.0.0.1", "default": "127.0.0.1",
"env": "METRICS_ADDRESS", "env": "METRICS_ADDRESS",
"type": environs.Env().str "type": environs.Env().str,
}, },
"metrics.port": { "metrics.port": {
"default": 8000, "default": 8000,
"env": "METRICS_PORT", "env": "METRICS_PORT",
"type": environs.Env().int "type": environs.Env().int,
}, },
"config_file": { "config_file": {
"default": "", "default": "",
"env": "CONFIG_FILE", "env": "CONFIG_FILE",
"type": environs.Env().str "type": environs.Env().str,
}, },
"logging.level": { "logging.level": {
"default": "WARNING", "default": "WARNING",
"env": "LOG_LEVEL", "env": "LOG_LEVEL",
"file": True, "file": True,
"type": environs.Env().str "type": environs.Env().str,
}, },
"logging.format": { "logging.format": {
"default": "console", "default": "console",
"env": "LOG_FORMAT", "env": "LOG_FORMAT",
"file": True, "file": True,
"type": environs.Env().str "type": environs.Env().str,
}, },
"output_file": { "output_file": {
"default": default_output_file, "default": default_output_file,
"env": "OUTPUT_FILE", "env": "OUTPUT_FILE",
"file": True, "file": True,
"type": environs.Env().str "type": environs.Env().str,
}, },
"output_file_mode": { "output_file_mode": {
"default": "0640", "default": "0640",
"env": "OUTPUT_FILE_MODE", "env": "OUTPUT_FILE_MODE",
"file": True, "file": True,
"type": environs.Env().str "type": environs.Env().str,
}, },
"loop_delay": { "loop_delay": {
"default": 300, "default": 300,
"env": "LOOP_DELAY", "env": "LOOP_DELAY",
"file": True, "file": True,
"type": environs.Env().int "type": environs.Env().int,
}, },
"service": { "service": {
"default": True, "default": True,
"env": "SERVICE", "env": "SERVICE",
"file": True, "file": True,
"type": environs.Env().bool "type": environs.Env().bool,
}, },
"exclude_state": { "exclude_state": {
"default": [], "default": [],
"env": "EXCLUDE_STATE", "env": "EXCLUDE_STATE",
"file": True, "file": True,
"type": environs.Env().list "type": environs.Env().list,
}, },
"exclude_vmid": { "exclude_vmid": {
"default": [], "default": [],
"env": "EXCLUDE_VMID", "env": "EXCLUDE_VMID",
"file": True, "file": True,
"type": environs.Env().list "type": environs.Env().list,
}, },
"include_vmid": { "include_vmid": {
"default": [], "default": [],
"env": "INCLUDE_VMID", "env": "INCLUDE_VMID",
"file": True, "file": True,
"type": environs.Env().list "type": environs.Env().list,
}, },
"exclude_tags": { "exclude_tags": {
"default": [], "default": [],
"env": "EXCLUDE_TAGS", "env": "EXCLUDE_TAGS",
"file": True, "file": True,
"type": environs.Env().list "type": environs.Env().list,
}, },
"include_tags": { "include_tags": {
"default": [], "default": [],
"env": "INCLUDE_TAGS", "env": "INCLUDE_TAGS",
"file": True, "file": True,
"type": environs.Env().list "type": environs.Env().list,
}, },
"pve.server": { "pve.server": {
"default": "", "default": "",
"env": "PVE_SERVER", "env": "PVE_SERVER",
"file": True, "file": True,
"type": environs.Env().str "type": environs.Env().str,
}, },
"pve.user": { "pve.user": {
"default": "", "default": "",
"env": "PVE_USER", "env": "PVE_USER",
"file": True, "file": True,
"type": environs.Env().str "type": environs.Env().str,
}, },
"pve.password": { "pve.password": {
"default": "", "default": "",
"env": "PVE_PASSWORD", "env": "PVE_PASSWORD",
"file": True, "file": True,
"type": environs.Env().str "type": environs.Env().str,
},
"pve.token_name": {
"default": "",
"env": "PVE_TOKEN_NAME",
"file": True,
"type": environs.Env().str,
},
"pve.token_value": {
"default": "",
"env": "PVE_TOKEN_VALUE",
"file": True,
"type": environs.Env().str,
}, },
"pve.auth_timeout": { "pve.auth_timeout": {
"default": 5, "default": 5,
"env": "PVE_AUTH_TIMEOUT", "env": "PVE_AUTH_TIMEOUT",
"file": True, "file": True,
"type": environs.Env().int "type": environs.Env().int,
}, },
"pve.verify_ssl": { "pve.verify_ssl": {
"default": True, "default": True,
"env": "PVE_VERIFY_SSL", "env": "PVE_VERIFY_SSL",
"file": True, "file": True,
"type": environs.Env().bool "type": environs.Env().bool,
}, },
} }
def __init__(self, args={}): def __init__(self, args=None):
""" """
Initialize a new settings class. Initialize a new settings class.
@ -159,7 +170,10 @@ class Config():
:returns: None :returns: None
""" """
self._args = args if args is None:
self._args = {}
else:
self._args = args
self._schema = None self._schema = None
self.config_file = default_config_file self.config_file = default_config_file
self.config = None self.config = None
@ -200,12 +214,12 @@ class Config():
value = item["type"](envname) value = item["type"](envname)
normalized = self._add_dict_branch(normalized, key.split("."), value) normalized = self._add_dict_branch(normalized, key.split("."), value)
except environs.EnvError as e: except environs.EnvError as e:
if '"{}" not set'.format(envname) in str(e): if f'"{envname}" not set' in str(e):
pass pass
else: else:
raise prometheuspvesd.exception.ConfigError( raise prometheuspvesd.exception.ConfigError(
"Unable to read environment variable", str(e) "Unable to read environment variable", str(e)
) ) from e
return normalized return normalized
@ -226,17 +240,18 @@ class Config():
for config in source_files: for config in source_files:
if config and os.path.exists(config): if config and os.path.exists(config):
with open(config, "r", encoding="utf8") as stream: with open(config, encoding="utf8") as stream:
s = stream.read() s = stream.read()
try: try:
file_dict = ruamel.yaml.YAML(typ="safe", pure=True).load(s) file_dict = ruamel.yaml.YAML(typ="safe", pure=True).load(s)
except ( except (
ruamel.yaml.composer.ComposerError, ruamel.yaml.scanner.ScannerError ruamel.yaml.composer.ComposerError,
ruamel.yaml.scanner.ScannerError,
) as e: ) as e:
message = "{} {}".format(e.context, e.problem) message = f"{e.context} {e.problem}"
raise prometheuspvesd.exception.ConfigError( raise prometheuspvesd.exception.ConfigError(
"Unable to read config file {}".format(config), message f"Unable to read config file {config}", message
) ) from e
if self._validate(file_dict): if self._validate(file_dict):
anyconfig.merge(defaults, file_dict, ac_merge=anyconfig.MS_DICTS) anyconfig.merge(defaults, file_dict, ac_merge=anyconfig.MS_DICTS)
@ -263,27 +278,26 @@ class Config():
if not os.path.isabs(path): if not os.path.isabs(path):
base = os.path.join(os.getcwd(), path) base = os.path.join(os.getcwd(), path)
return os.path.abspath(os.path.expanduser(os.path.expandvars(base))) return os.path.abspath(os.path.expanduser(os.path.expandvars(base)))
else:
return path return path
def _validate(self, config): def _validate(self, config):
try: try:
anyconfig.validate(config, self.schema, ac_schema_safe=False) anyconfig.validate(config, self.schema, ac_schema_safe=False)
except jsonschema.exceptions.ValidationError as e: except jsonschema.exceptions.ValidationError as e:
schema_error = "Failed validating '{validator}' in schema{schema}\n{message}".format( schema = format_as_index(list(e.relative_schema_path)[:-1], 0)
validator=e.validator, schema_error = f"Failed validating '{e.validator}' in schema {schema}\n{e.message}"
schema=format_as_index(list(e.relative_schema_path)[:-1], 0), raise prometheuspvesd.exception.ConfigError("Configuration error", schema_error) from e
message=e.message
)
raise prometheuspvesd.exception.ConfigError("Configuration error", schema_error)
return True return True
def _add_dict_branch(self, tree, vector, value): def _add_dict_branch(self, tree, vector, value):
key = vector[0] key = vector[0]
tree[key] = value \ tree[key] = (
if len(vector) == 1 \ value
else self._add_dict_branch(tree[key] if key in tree else {}, vector[1:], value) if len(vector) == 1
else self._add_dict_branch(tree.get(key, {}), vector[1:], value)
)
return tree return tree

View File

@ -6,15 +6,13 @@ import json
import re import re
from collections import defaultdict from collections import defaultdict
from prometheus_client import Gauge from prometheus_client import Gauge, Summary
from prometheus_client import Summary
from prometheuspvesd.client import ProxmoxClient from prometheuspvesd.client import ProxmoxClient
from prometheuspvesd.config import SingleConfig from prometheuspvesd.config import SingleConfig
from prometheuspvesd.exception import APIError from prometheuspvesd.exception import APIError
from prometheuspvesd.logger import SingleLog from prometheuspvesd.logger import SingleLog
from prometheuspvesd.model import Host from prometheuspvesd.model import Host, HostList
from prometheuspvesd.model import HostList
PROPAGATION_TIME = Summary( PROPAGATION_TIME = Summary(
"pve_sd_propagate_seconds", "Time spent propagating the inventory from PVE" "pve_sd_propagate_seconds", "Time spent propagating the inventory from PVE"
@ -22,7 +20,7 @@ PROPAGATION_TIME = Summary(
HOST_GAUGE = Gauge("pve_sd_hosts", "Number of hosts discovered by PVE SD") HOST_GAUGE = Gauge("pve_sd_hosts", "Number of hosts discovered by PVE SD")
class Discovery(): class Discovery:
"""Prometheus PVE Service Discovery.""" """Prometheus PVE Service Discovery."""
def __init__(self): def __init__(self):
@ -63,10 +61,10 @@ class Discovery():
try: try:
if self.client.get_agent_info(pve_node, pve_type, vmid) is not None: if self.client.get_agent_info(pve_node, pve_type, vmid) is not None:
networks = self.client.get_network_interfaces(pve_node, vmid) networks = self.client.get_network_interfaces(pve_node, vmid)
except Exception: # noqa # nosec except Exception: # noqa
pass pass
if type(networks) is list: if isinstance(networks, list):
for network in networks: for network in networks:
for ip_address in network.get("ip-addresses", []): for ip_address in network.get("ip-addresses", []):
if ip_address["ip-address-type"] == "ipv4" and not ipv4_address: if ip_address["ip-address-type"] == "ipv4" and not ipv4_address:
@ -77,7 +75,7 @@ class Discovery():
config = self.client.get_instance_config(pve_node, pve_type, vmid) config = self.client.get_instance_config(pve_node, pve_type, vmid)
if config and not ipv4_address: if config and not ipv4_address:
try: try:
if "ipconfig0" in config.keys(): if "ipconfig0" in config:
sources = [config["net0"], config["ipconfig0"]] sources = [config["net0"], config["ipconfig0"]]
else: else:
sources = [config["net0"]] sources = [config["net0"]]
@ -87,12 +85,12 @@ class Discovery():
if find and find.group(1): if find and find.group(1):
ipv4_address = find.group(1) ipv4_address = find.group(1)
break break
except Exception: # noqa # nosec except Exception: # noqa
pass pass
if config and not ipv6_address: if config and not ipv6_address:
try: try:
if "ipconfig0" in config.keys(): if "ipconfig0" in config:
sources = [config["net0"], config["ipconfig0"]] sources = [config["net0"], config["ipconfig0"]]
else: else:
sources = [config["net0"]] sources = [config["net0"]]
@ -104,7 +102,7 @@ class Discovery():
if find and find.group(1): if find and find.group(1):
ipv6_address = find.group(1) ipv6_address = find.group(1)
break break
except Exception: # noqa # nosec except Exception: # noqa
pass pass
return ipv4_address, ipv6_address return ipv4_address, ipv6_address
@ -113,17 +111,22 @@ class Discovery():
filtered = [] filtered = []
for item in pve_list: for item in pve_list:
obj = defaultdict(dict, item) obj = defaultdict(dict, item)
tags = []
tags_excl = self.config.config["exclude_tags"]
if isinstance(obj["tags"], str):
tags = obj["tags"].split(";")
self.logger.debug(f"vmid {obj['vmid']}: discovered tags: {tags}")
if ( if (
len(self.config.config["include_vmid"]) > 0 len(self.config.config["include_vmid"]) > 0
and str(obj["vmid"]) not in self.config.config["include_vmid"] and str(obj["vmid"]) not in self.config.config["include_vmid"]
): ):
continue continue
if ( if len(self.config.config["include_tags"]) > 0 and (
len(self.config.config["include_tags"]) > 0 and ( bool(obj["tags"]) is False # continue if tags is not set
bool(obj["tags"]) is False # continue if tags is not set or set(tags).isdisjoint(self.config.config["include_tags"])
or set(obj["tags"].split(",")).isdisjoint(self.config.config["include_tags"])
)
): ):
continue continue
@ -136,10 +139,11 @@ class Discovery():
if str(obj["vmid"]) in self.config.config["exclude_vmid"]: if str(obj["vmid"]) in self.config.config["exclude_vmid"]:
continue continue
if ( if isinstance(obj["tags"], str) and not set(tags).isdisjoint(tags_excl):
isinstance(obj["tags"], str) self.logger.debug(
and not set(obj["tags"].split(",")).isdisjoint(self.config.config["exclude_tags"]) f"vmid {obj['vmid']}: "
): f"excluded by tags: {list(set(tags).intersection(tags_excl))}"
)
continue continue
filtered.append(item.copy()) filtered.append(item.copy())
@ -158,20 +162,21 @@ class Discovery():
@PROPAGATION_TIME.time() @PROPAGATION_TIME.time()
def propagate(self): def propagate(self):
self.host_list.clear() self.host_list.clear()
nodelist = self._get_names(self.client.get_nodes(), "node")
for node in self._get_names(self.client.get_nodes(), "node"): self.logger.info(f"Discovered nodes: {','.join(nodelist)}")
for node in nodelist:
try: try:
qemu_list = self._filter(self.client.get_all_vms(node)) qemu_list = self._filter(self.client.get_all_vms(node))
container_list = self._filter(self.client.get_all_containers(node)) container_list = self._filter(self.client.get_all_containers(node))
except Exception as e: # noqa except Exception as e:
raise APIError(str(e)) raise APIError(str(e)) from e
# Merge QEMU and Containers lists from this node # Merge QEMU and Containers lists from this node
instances = self._get_variables(qemu_list, "qemu").copy() instances = self._get_variables(qemu_list, "qemu").copy()
instances.update(self._get_variables(container_list, "container")) instances.update(self._get_variables(container_list, "container"))
HOST_GAUGE.set(len(instances)) HOST_GAUGE.set(len(instances))
self.logger.info("Found {} targets".format(len(instances))) self.logger.info(f"{node}: Found {len(instances)} targets")
for host in instances: for host in instances:
host_meta = instances[host] host_meta = instances[host]
vmid = host_meta["proxmox_vmid"] vmid = host_meta["proxmox_vmid"]
@ -184,11 +189,11 @@ class Discovery():
config = self.client.get_instance_config(node, pve_type, vmid) config = self.client.get_instance_config(node, pve_type, vmid)
try: try:
description = (config["description"]) description = config["description"]
except KeyError: except KeyError:
description = None description = None
except Exception as e: # noqa except Exception as e:
raise APIError(str(e)) raise APIError(str(e)) from e
try: try:
metadata = json.loads(description) metadata = json.loads(description)
@ -216,6 +221,6 @@ class Discovery():
prom_host.add_label("groups", ",".join(metadata["groups"])) prom_host.add_label("groups", ",".join(metadata["groups"]))
self.host_list.add_host(prom_host) self.host_list.add_host(prom_host)
self.logger.debug("Discovered {}".format(prom_host)) self.logger.debug(f"Discovered {prom_host}")
return self.host_list return self.host_list

View File

@ -6,8 +6,7 @@ class PrometheusSDError(Exception):
"""Generic exception class for Prometheus-pve-sd.""" """Generic exception class for Prometheus-pve-sd."""
def __init__(self, msg, original_exception=""): def __init__(self, msg, original_exception=""):
super(PrometheusSDError, super().__init__(f"{msg}\n{original_exception}")
self).__init__("{msg}\n{org}".format(msg=msg, org=original_exception))
self.original_exception = original_exception self.original_exception = original_exception

View File

@ -8,8 +8,7 @@ import sys
import colorama import colorama
from pythonjsonlogger import jsonlogger from pythonjsonlogger import jsonlogger
from prometheuspvesd.utils import Singleton from prometheuspvesd.utils import Singleton, to_bool
from prometheuspvesd.utils import to_bool
CONSOLE_FORMAT = "{}{}[%(levelname)s]{} %(message)s" CONSOLE_FORMAT = "{}{}[%(levelname)s]{} %(message)s"
JSON_FORMAT = "%(asctime)s %(levelname)s %(message)s" JSON_FORMAT = "%(asctime)s %(levelname)s %(message)s"
@ -26,7 +25,7 @@ def _should_do_markup():
colorama.init(autoreset=True, strip=not _should_do_markup()) colorama.init(autoreset=True, strip=not _should_do_markup())
class LogFilter(object): class LogFilter:
"""A custom log filter which excludes log messages above the logged level.""" """A custom log filter which excludes log messages above the logged level."""
def __init__(self, level): def __init__(self, level):
@ -47,22 +46,22 @@ class LogFilter(object):
class SimpleFormatter(logging.Formatter): class SimpleFormatter(logging.Formatter):
"""Logging Formatter for simple logs.""" """Logging Formatter for simple logs."""
def format(self, record): # noqa def format(self, record):
return logging.Formatter.format(self, record) return logging.Formatter.format(self, record)
class MultilineFormatter(logging.Formatter): class MultilineFormatter(logging.Formatter):
"""Logging Formatter to reset color after newline characters.""" """Logging Formatter to reset color after newline characters."""
def format(self, record): # noqa def format(self, record):
record.msg = record.msg.replace("\n", "\n{}... ".format(colorama.Style.RESET_ALL)) record.msg = record.msg.replace("\n", f"\n{colorama.Style.RESET_ALL}... ")
return logging.Formatter.format(self, record) return logging.Formatter.format(self, record)
class MultilineJsonFormatter(jsonlogger.JsonFormatter): class MultilineJsonFormatter(jsonlogger.JsonFormatter):
"""Logging Formatter to remove newline characters.""" """Logging Formatter to remove newline characters."""
def format(self, record): # noqa def format(self, record):
record.msg = record.msg.replace("\n", " ") record.msg = record.msg.replace("\n", " ")
return jsonlogger.JsonFormatter.format(self, record) return jsonlogger.JsonFormatter.format(self, record)
@ -230,7 +229,7 @@ class Log:
:returns: string :returns: string
""" """
return "{}{}{}".format(color, msg, colorama.Style.RESET_ALL) return f"{color}{msg}{colorama.Style.RESET_ALL}"
def sysexit(self, code=1): def sysexit(self, code=1):
sys.exit(code) sys.exit(code)

View File

@ -19,8 +19,10 @@ class Host:
self.add_label("vmid", vmid) self.add_label("vmid", vmid)
def __str__(self): def __str__(self):
return f"{self.hostname}({self.vmid}): {self.pve_type} \ return (
{self.ipv4_address} {self.ipv6_address}" f"{self.hostname}({self.vmid}): "
f"{self.pve_type} {self.ipv4_address} {self.ipv6_address}"
)
def add_label(self, key, value): def add_label(self, key, value):
key = key.replace("-", "_").replace(" ", "_") key = key.replace("-", "_").replace(" ", "_")

View File

@ -24,5 +24,7 @@ pve:
server: proxmox.example.com server: proxmox.example.com
user: root user: root
password: secure password: secure
token_name: pve_sd
token_value: 01234567-89ab-cdef-0123-456789abcdef
auth_timeout: 5 auth_timeout: 5
verify_ssl: true verify_ssl: true

View File

@ -3,8 +3,7 @@
import environs import environs
import pytest import pytest
from prometheuspvesd.model import Host from prometheuspvesd.model import Host, HostList
from prometheuspvesd.model import HostList
@pytest.fixture @pytest.fixture
@ -13,119 +12,118 @@ def builtins():
"metrics.enabled": { "metrics.enabled": {
"default": True, "default": True,
"env": "METRICS_ENABLED", "env": "METRICS_ENABLED",
"type": environs.Env().bool "type": environs.Env().bool,
}, },
"metrics.address": { "metrics.address": {
"default": "127.0.0.1", "default": "127.0.0.1",
"env": "METRICS_ADDRESS", "env": "METRICS_ADDRESS",
"type": environs.Env().str "type": environs.Env().str,
},
"metrics.port": {
"default": 8000,
"env": "METRICS_PORT",
"type": environs.Env().int
},
"config_file": {
"default": "",
"env": "CONFIG_FILE",
"type": environs.Env().str
}, },
"metrics.port": {"default": 8000, "env": "METRICS_PORT", "type": environs.Env().int},
"config_file": {"default": "", "env": "CONFIG_FILE", "type": environs.Env().str},
"logging.level": { "logging.level": {
"default": "WARNING", "default": "WARNING",
"env": "LOG_LEVEL", "env": "LOG_LEVEL",
"file": True, "file": True,
"type": environs.Env().str "type": environs.Env().str,
}, },
"logging.format": { "logging.format": {
"default": "console", "default": "console",
"env": "LOG_FORMAT", "env": "LOG_FORMAT",
"file": True, "file": True,
"type": environs.Env().str "type": environs.Env().str,
}, },
"output_file": { "output_file": {
"default": "dummy", "default": "dummy",
"env": "OUTPUT_FILE", "env": "OUTPUT_FILE",
"file": True, "file": True,
"type": environs.Env().str "type": environs.Env().str,
}, },
"output_file_mode": { "output_file_mode": {
"default": "0640", "default": "0640",
"env": "OUTPUT_FILE_MODE", "env": "OUTPUT_FILE_MODE",
"file": True, "file": True,
"type": environs.Env().str "type": environs.Env().str,
}, },
"loop_delay": { "loop_delay": {
"default": 300, "default": 300,
"env": "LOOP_DELAY", "env": "LOOP_DELAY",
"file": True, "file": True,
"type": environs.Env().int "type": environs.Env().int,
},
"service": {
"default": False,
"env": "SERVICE",
"file": True,
"type": environs.Env().bool
}, },
"service": {"default": False, "env": "SERVICE", "file": True, "type": environs.Env().bool},
"exclude_state": { "exclude_state": {
"default": [], "default": [],
"env": "EXCLUDE_STATE", "env": "EXCLUDE_STATE",
"file": True, "file": True,
"type": environs.Env().list "type": environs.Env().list,
}, },
"exclude_vmid": { "exclude_vmid": {
"default": [], "default": [],
"env": "EXCLUDE_VMID", "env": "EXCLUDE_VMID",
"file": True, "file": True,
"type": environs.Env().list "type": environs.Env().list,
}, },
"exclude_tags": { "exclude_tags": {
"default": [], "default": [],
"env": "EXCLUDE_TAGS", "env": "EXCLUDE_TAGS",
"file": True, "file": True,
"type": environs.Env().list "type": environs.Env().list,
}, },
"include_vmid": { "include_vmid": {
"default": [], "default": [],
"env": "INCLUDE_VMID", "env": "INCLUDE_VMID",
"file": True, "file": True,
"type": environs.Env().list "type": environs.Env().list,
}, },
"include_tags": { "include_tags": {
"default": [], "default": [],
"env": "INCLUDE_TAGS", "env": "INCLUDE_TAGS",
"file": True, "file": True,
"type": environs.Env().list "type": environs.Env().list,
}, },
"pve.server": { "pve.server": {
"default": "dummyserver", "default": "dummyserver",
"env": "PVE_SERVER", "env": "PVE_SERVER",
"file": True, "file": True,
"type": environs.Env().str "type": environs.Env().str,
}, },
"pve.user": { "pve.user": {
"default": "dummyuser", "default": "dummyuser",
"env": "PVE_USER", "env": "PVE_USER",
"file": True, "file": True,
"type": environs.Env().str "type": environs.Env().str,
}, },
"pve.password": { "pve.password": {
"default": "dummypass", "default": "dummypass",
"env": "PVE_PASSWORD", "env": "PVE_PASSWORD",
"file": True, "file": True,
"type": environs.Env().str "type": environs.Env().str,
},
"pve.token_name": {
"default": "dummyname",
"env": "PVE_TOKEN_NAME",
"file": True,
"type": environs.Env().str,
},
"pve.token_value": {
"default": "dummyvalue",
"env": "PVE_TOKEN_VALUE",
"file": True,
"type": environs.Env().str,
}, },
"pve.auth_timeout": { "pve.auth_timeout": {
"default": 5, "default": 5,
"env": "PVE_AUTH_TIMEOUT", "env": "PVE_AUTH_TIMEOUT",
"file": True, "file": True,
"type": environs.Env().int "type": environs.Env().int,
}, },
"pve.verify_ssl": { "pve.verify_ssl": {
"default": True, "default": True,
"env": "PVE_VERIFY_SSL", "env": "PVE_VERIFY_SSL",
"file": True, "file": True,
"type": environs.Env().bool "type": environs.Env().bool,
} },
} }
@ -137,16 +135,9 @@ def defaults():
"exclude_vmid": [], "exclude_vmid": [],
"include_tags": [], "include_tags": [],
"include_vmid": [], "include_vmid": [],
"logging": { "logging": {"format": "console", "level": "WARNING"},
"format": "console",
"level": "WARNING"
},
"loop_delay": 300, "loop_delay": 300,
"metrics": { "metrics": {"address": "127.0.0.1", "enabled": True, "port": 8000},
"address": "127.0.0.1",
"enabled": True,
"port": 8000
},
"output_file": "dummy", "output_file": "dummy",
"output_file_mode": "0640", "output_file_mode": "0640",
"pve": { "pve": {
@ -154,7 +145,9 @@ def defaults():
"password": "", "password": "",
"server": "", "server": "",
"user": "", "user": "",
"verify_ssl": True "token_name": "",
"token_value": "",
"verify_ssl": True,
}, },
"service": True, "service": True,
} }
@ -162,20 +155,22 @@ def defaults():
@pytest.fixture @pytest.fixture
def nodes(): def nodes():
return [{ return [
"level": "", {
"id": "node/example-node", "level": "",
"disk": 4783488, "id": "node/example-node",
"cpu": 0.0935113631167406, "disk": 4783488,
"maxcpu": 24, "cpu": 0.0935113631167406,
"maxmem": 142073272990, "maxcpu": 24,
"mem": 135884478304, "maxmem": 142073272990,
"node": "example-node", "mem": 135884478304,
"type": "node", "node": "example-node",
"status": "online", "type": "node",
"maxdisk": 504209920, "status": "online",
"uptime": 200 "maxdisk": 504209920,
}] "uptime": 200,
}
]
@pytest.fixture @pytest.fixture
@ -198,7 +193,7 @@ def qemus():
"status": "running", "status": "running",
"netout": 12159205236, "netout": 12159205236,
"mem": 496179157, "mem": 496179157,
"tags": "unmonitored,excluded,postgres" "tags": "unmonitored;excluded;postgres",
}, },
{ {
"diskwrite": 0, "diskwrite": 0,
@ -216,7 +211,7 @@ def qemus():
"disk": 0, "disk": 0,
"status": "running", "status": "running",
"netout": 12159205236, "netout": 12159205236,
"mem": 496179157 "mem": 496179157,
}, },
{ {
"diskwrite": 0, "diskwrite": 0,
@ -235,7 +230,7 @@ def qemus():
"status": "prelaunch", "status": "prelaunch",
"netout": 12159205236, "netout": 12159205236,
"mem": 496179157, "mem": 496179157,
"tags": "monitored" "tags": "monitored",
}, },
] ]
@ -247,19 +242,17 @@ def instance_config():
"description": '{"groups": "test-group"}', "description": '{"groups": "test-group"}',
"net0": "virtio=D8-85-75-47-2E-8D,bridge=vmbr122,ip=192.0.2.25,ip=2001:db8::666:77:8888", "net0": "virtio=D8-85-75-47-2E-8D,bridge=vmbr122,ip=192.0.2.25,ip=2001:db8::666:77:8888",
"cpu": 2, "cpu": 2,
"cores": 2 "cores": 2,
} }
@pytest.fixture @pytest.fixture
def agent_info(): def agent_info():
return { return {
"supported_commands": [{ "supported_commands": [
"name": "guest-network-get-interfaces", {"name": "guest-network-get-interfaces", "enabled": True, "success-response": True}
"enabled": True, ],
"success-response": True "version": "5.2.0",
}],
"version": "5.2.0"
} }
@ -296,16 +289,8 @@ def networks():
{ {
"hardware-address": "00:00:00:00:00:00", "hardware-address": "00:00:00:00:00:00",
"ip-addresses": [ "ip-addresses": [
{ {"ip-address": "127.0.0.1", "ip-address-type": "ipv4", "prefix": 8},
"ip-address": "127.0.0.1", {"ip-address": "::1", "ip-address-type": "ipv6", "prefix": 128},
"ip-address-type": "ipv4",
"prefix": 8
},
{
"ip-address": "::1",
"ip-address-type": "ipv6",
"prefix": 128
},
], ],
"name": "lo", "name": "lo",
"statistics": { "statistics": {
@ -316,26 +301,18 @@ def networks():
"tx-bytes": 9280, "tx-bytes": 9280,
"tx-dropped": 0, "tx-dropped": 0,
"tx-errs": 0, "tx-errs": 0,
"tx-packets": 92 "tx-packets": 92,
} },
}, },
{ {
"hardware-address": "92:0b:bd:c1:f8:39", "hardware-address": "92:0b:bd:c1:f8:39",
"ip-addresses": [ "ip-addresses": [
{ {"ip-address": "192.0.2.1", "ip-address-type": "ipv4", "prefix": 32},
"ip-address": "192.0.2.1", {"ip-address": "192.0.2.4", "ip-address-type": "ipv4", "prefix": 32},
"ip-address-type": "ipv4",
"prefix": 32
},
{
"ip-address": "192.0.2.4",
"ip-address-type": "ipv4",
"prefix": 32
},
{ {
"ip-address": "2001:db8:3333:4444:5555:6666:7777:8888", "ip-address": "2001:db8:3333:4444:5555:6666:7777:8888",
"ip-address-type": "ipv6", "ip-address-type": "ipv6",
"prefix": 64 "prefix": 64,
}, },
], ],
"name": "eth0", "name": "eth0",
@ -347,13 +324,10 @@ def networks():
"tx-bytes": 12185866619, "tx-bytes": 12185866619,
"tx-dropped": 0, "tx-dropped": 0,
"tx-errs": 0, "tx-errs": 0,
"tx-packets": 14423878 "tx-packets": 14423878,
} },
},
{
"hardware-address": "ba:97:85:bd:9a:a5",
"name": "eth1"
}, },
{"hardware-address": "ba:97:85:bd:9a:a5", "name": "eth1"},
] ]
@ -369,31 +343,35 @@ def inventory():
@pytest.fixture @pytest.fixture
def labels(): def labels():
return [{ return [
"targets": ["100.example.com"], {
"labels": { "targets": ["100.example.com"],
"__meta_pve_ipv4": "192.0.2.1", "labels": {
"__meta_pve_ipv6": "False", "__meta_pve_ipv4": "192.0.2.1",
"__meta_pve_name": "100.example.com", "__meta_pve_ipv6": "False",
"__meta_pve_type": "qemu", "__meta_pve_name": "100.example.com",
"__meta_pve_vmid": "100" "__meta_pve_type": "qemu",
} "__meta_pve_vmid": "100",
}, { },
"targets": ["101.example.com"], },
"labels": { {
"__meta_pve_ipv4": "192.0.2.2", "targets": ["101.example.com"],
"__meta_pve_ipv6": "False", "labels": {
"__meta_pve_name": "101.example.com", "__meta_pve_ipv4": "192.0.2.2",
"__meta_pve_type": "qemu", "__meta_pve_ipv6": "False",
"__meta_pve_vmid": "101" "__meta_pve_name": "101.example.com",
} "__meta_pve_type": "qemu",
}, { "__meta_pve_vmid": "101",
"targets": ["102.example.com"], },
"labels": { },
"__meta_pve_ipv4": "192.0.2.3", {
"__meta_pve_ipv6": "False", "targets": ["102.example.com"],
"__meta_pve_name": "102.example.com", "labels": {
"__meta_pve_type": "qemu", "__meta_pve_ipv4": "192.0.2.3",
"__meta_pve_vmid": "102" "__meta_pve_ipv6": "False",
} "__meta_pve_name": "102.example.com",
}] "__meta_pve_type": "qemu",
"__meta_pve_vmid": "102",
},
},
]

View File

@ -1,8 +1,12 @@
"""Pytest conftest fixtures.""" """Pytest conftest fixtures."""
import logging
import os import os
import sys import sys
from contextlib import contextmanager
import pytest import pytest
from _pytest.logging import LogCaptureHandler
from prometheuspvesd.utils import Singleton from prometheuspvesd.utils import Singleton
@ -14,9 +18,43 @@ def reset_singletons():
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def reset_os_environment(): def reset_os_environment():
os.environ = {} os.environ.clear()
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def reset_sys_argv(): def reset_sys_argv():
sys.argv = ["prometheus-pve-sd"] sys.argv = ["prometheus-pve-sd"]
@contextmanager
def local_caplog_fn(level=logging.INFO, name="prometheuspvesd"):
"""
Context manager that captures records from non-propagating loggers.
After the end of the 'with' statement, the log level is restored to its original
value. Code adapted from https://github.com/pytest-dev/pytest/issues/3697#issuecomment-790925527.
:param int level: The level.
:param logging.Logger logger: The logger to update.
"""
logger = logging.getLogger(name)
old_level = logger.level
logger.setLevel(level)
handler = LogCaptureHandler()
logger.addHandler(handler)
try:
yield handler
finally:
logger.setLevel(old_level)
logger.removeHandler(handler)
@pytest.fixture
def local_caplog():
"""Fixture that yields a context manager for capturing records from non-propagating loggers."""
yield local_caplog_fn

View File

@ -1,4 +1,5 @@
"""Test CLI class.""" """Test CLI class."""
import json import json
import pytest import pytest
@ -29,10 +30,68 @@ def test_cli_required_error(mocker, capsys):
assert e.value.code == 1 assert e.value.code == 1
@pytest.mark.parametrize(
"testinput",
[
{"pve.user": "dummy", "pve.password": "", "pve.token_name": "", "pve.token_value": ""},
{
"pve.user": "dummy",
"pve.password": "",
"pve.token_name": "dummy",
"pve.token_value": "",
},
{
"pve.user": "dummy",
"pve.password": "",
"pve.token_name": "",
"pve.token_value": "dummy",
},
],
)
def test_cli_auth_required_error(mocker, capsys, builtins, testinput):
for key, value in testinput.items():
builtins[key]["default"] = value
mocker.patch.dict(Config.SETTINGS, builtins)
mocker.patch.object(ProxmoxClient, "_auth", return_value=mocker.create_autospec(ProxmoxAPI))
mocker.patch.object(PrometheusSD, "_fetch", return_value=True)
with pytest.raises(SystemExit) as e:
PrometheusSD()
stdout, stderr = capsys.readouterr()
assert (
"Either 'pve.password' or 'pve.token_name' and 'pve.token_value' are required but not set"
in stderr
)
assert e.value.code == 1
@pytest.mark.parametrize(
"testinput",
[
{"pve.password": "dummy", "pve.token_name": "", "pve.token_value": ""},
{"pve.password": "", "pve.token_name": "dummy", "pve.token_value": "dummy"},
],
)
def test_cli_auth_no_error(mocker, builtins, testinput):
for key, value in testinput.items():
builtins[key]["default"] = value
mocker.patch.dict(Config.SETTINGS, builtins)
mocker.patch.object(ProxmoxClient, "_auth", return_value=mocker.create_autospec(ProxmoxAPI))
mocker.patch.object(PrometheusSD, "_fetch", return_value=True)
psd = PrometheusSD()
for key, value in testinput.items():
assert psd.config.config["pve"][key.split(".")[1]] == value
def test_cli_config_error(mocker, capsys): def test_cli_config_error(mocker, capsys):
mocker.patch( mocker.patch(
"prometheuspvesd.config.SingleConfig.__init__", "prometheuspvesd.config.SingleConfig.__init__",
side_effect=prometheuspvesd.exception.ConfigError("Dummy Config Exception") side_effect=prometheuspvesd.exception.ConfigError("Dummy Config Exception"),
) )
mocker.patch.object(ProxmoxClient, "_auth", return_value=mocker.create_autospec(ProxmoxAPI)) mocker.patch.object(ProxmoxClient, "_auth", return_value=mocker.create_autospec(ProxmoxAPI))
mocker.patch.object(PrometheusSD, "_fetch", return_value=True) mocker.patch.object(PrometheusSD, "_fetch", return_value=True)

View File

@ -1,4 +1,5 @@
"""Test Config class.""" """Test Config class."""
import pytest import pytest
import ruamel.yaml import ruamel.yaml
@ -19,11 +20,13 @@ def test_yaml_config(mocker, defaults):
defaults["pve"]["user"] = "root" defaults["pve"]["user"] = "root"
defaults["pve"]["password"] = "secure" defaults["pve"]["password"] = "secure"
defaults["pve"]["server"] = "proxmox.example.com" defaults["pve"]["server"] = "proxmox.example.com"
defaults["pve"]["token_name"] = "pve_sd"
defaults["pve"]["token_value"] = "01234567-89ab-cdef-0123-456789abcdef"
assert config.config == defaults assert config.config == defaults
def test_yaml_config_error(mocker, capsys): def test_yaml_config_error(mocker):
mocker.patch( mocker.patch(
"prometheuspvesd.config.default_config_file", "./prometheuspvesd/test/data/config.yml" "prometheuspvesd.config.default_config_file", "./prometheuspvesd/test/data/config.yml"
) )

View File

@ -1,5 +1,7 @@
"""Test Discovery class.""" """Test Discovery class."""
import logging
import pytest import pytest
from proxmoxer import ProxmoxAPI from proxmoxer import ProxmoxAPI
@ -11,6 +13,10 @@ pytest_plugins = [
] ]
def records_to_messages(records):
return [r.getMessage() for r in records]
@pytest.fixture @pytest.fixture
def discovery(mocker): def discovery(mocker):
mocker.patch.object(ProxmoxClient, "_auth", return_value=mocker.create_autospec(ProxmoxAPI)) mocker.patch.object(ProxmoxClient, "_auth", return_value=mocker.create_autospec(ProxmoxAPI))
@ -32,19 +38,27 @@ def test_exclude_state(discovery, qemus):
assert len(filtered) == 2 assert len(filtered) == 2
def test_exclude_tags(discovery, qemus): def test_exclude_tags(discovery, qemus, local_caplog):
discovery.config.config["exclude_tags"] = ["unmonitored"] discovery.config.config["exclude_tags"] = ["unmonitored"]
filtered = discovery._filter(qemus)
with local_caplog(level=logging.DEBUG) as caplog:
filtered = discovery._filter(qemus)
assert (
"vmid 100: discovered tags: ['unmonitored', 'excluded', 'postgres']"
in records_to_messages(caplog.records)
)
assert "vmid 100: excluded by tags: ['unmonitored']"
assert len(filtered) == 2 assert len(filtered) == 2
@pytest.mark.parametrize( @pytest.mark.parametrize(
"testinput,expected", [ "testinput,expected",
[
(["monitored"], 1), (["monitored"], 1),
(["monitored", "postgres"], 2), (["monitored", "postgres"], 2),
([], 3), ([], 3),
] ],
) )
def test_include_tags(discovery, qemus, testinput, expected): def test_include_tags(discovery, qemus, testinput, expected):
discovery.config.config["include_tags"] = testinput discovery.config.config["include_tags"] = testinput
@ -53,10 +67,13 @@ def test_include_tags(discovery, qemus, testinput, expected):
assert len(filtered) == expected assert len(filtered) == expected
@pytest.mark.parametrize("testinput,expected", [ @pytest.mark.parametrize(
(["101", "100"], 2), "testinput,expected",
([], 3), [
]) (["101", "100"], 2),
([], 3),
],
)
def test_include_vmid(discovery, qemus, testinput, expected): def test_include_vmid(discovery, qemus, testinput, expected):
discovery.config.config["include_vmid"] = testinput discovery.config.config["include_vmid"] = testinput
filtered = discovery._filter(qemus) filtered = discovery._filter(qemus)

View File

@ -1,4 +1,5 @@
"""Test Host class.""" """Test Host class."""
import pytest import pytest
from prometheuspvesd.model import Host from prometheuspvesd.model import Host
@ -9,34 +10,41 @@ pytest_plugins = [
@pytest.mark.parametrize( @pytest.mark.parametrize(
"testinput,expected", [ "testinput,expected",
({ [
"vmid": 101, (
"hostname": "host1", {
"ipv4_address": False, "vmid": 101,
"ipv6_address": False, "hostname": "host1",
"pve_type": "qemu", "ipv4_address": False,
}, { "ipv6_address": False,
"__meta_pve_vmid": "101", "pve_type": "qemu",
"__meta_pve_name": "host1", },
"__meta_pve_ipv4": "False", {
"__meta_pve_ipv6": "False", "__meta_pve_vmid": "101",
"__meta_pve_type": "qemu", "__meta_pve_name": "host1",
}), "__meta_pve_ipv4": "False",
({ "__meta_pve_ipv6": "False",
"vmid": "202", "__meta_pve_type": "qemu",
"hostname": "host2", },
"ipv4_address": "129.168.0.1", ),
"ipv6_address": "2001:db8:3333:4444:5555:6666:7777:8888", (
"pve_type": "qemu", {
}, { "vmid": "202",
"__meta_pve_vmid": "202", "hostname": "host2",
"__meta_pve_name": "host2", "ipv4_address": "129.168.0.1",
"__meta_pve_ipv4": "129.168.0.1", "ipv6_address": "2001:db8:3333:4444:5555:6666:7777:8888",
"__meta_pve_ipv6": "2001:db8:3333:4444:5555:6666:7777:8888", "pve_type": "qemu",
"__meta_pve_type": "qemu", },
}), {
] "__meta_pve_vmid": "202",
"__meta_pve_name": "host2",
"__meta_pve_ipv4": "129.168.0.1",
"__meta_pve_ipv6": "2001:db8:3333:4444:5555:6666:7777:8888",
"__meta_pve_type": "qemu",
},
),
],
) )
def test_host(testinput, expected): def test_host(testinput, expected):
host = Host( host = Host(

View File

@ -1,7 +1,29 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Global utility methods and classes.""" """Global utility methods and classes."""
from distutils.util import strtobool
def strtobool(value):
"""Convert a string representation of truth to true or false."""
_map = {
"y": True,
"yes": True,
"t": True,
"true": True,
"on": True,
"1": True,
"n": False,
"no": False,
"f": False,
"false": False,
"off": False,
"0": False,
}
try:
return _map[str(value).lower()]
except KeyError as err:
raise ValueError(f'"{value}" is not a valid bool value') from err
def to_bool(string): def to_bool(string):
@ -15,5 +37,5 @@ class Singleton(type):
def __call__(cls, *args, **kwargs): def __call__(cls, *args, **kwargs):
if cls not in cls._instances: if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls] return cls._instances[cls]

View File

@ -10,10 +10,10 @@ classifiers = [
"Natural Language :: English", "Natural Language :: English",
"Operating System :: POSIX", "Operating System :: POSIX",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Utilities", "Topic :: Utilities",
] ]
description = "Prometheus Service Discovery for Proxmox VE." description = "Prometheus Service Discovery for Proxmox VE."
@ -29,66 +29,108 @@ repository = "https://github.com/thegeeklab/prometheus-pve-sd/"
version = "0.0.0" version = "0.0.0"
[tool.poetry.dependencies] [tool.poetry.dependencies]
anyconfig = "0.13.0" anyconfig = "0.14.0"
appdirs = "1.4.4" appdirs = "1.4.4"
colorama = "0.4.6" colorama = "0.4.6"
environs = "9.5.0" environs = "11.2.0"
jsonschema = "4.17.0" jsonschema = "4.23.0"
nested-lookup = "0.2.25" nested-lookup = "0.2.25"
prometheus-client = "0.15.0" prometheus-client = "0.21.0"
proxmoxer = "1.3.1" proxmoxer = "2.1.0"
python = "^3.7.0" python = "^3.10.0"
python-json-logger = "2.0.4" python-json-logger = "2.0.7"
requests = "2.28.1" requests = "2.32.3"
"ruamel.yaml" = "0.17.21" "ruamel.yaml" = "0.18.6"
[tool.poetry.dev-dependencies]
bandit = "1.7.4"
flake8 = "5.0.4"
flake8-blind-except = "0.2.1"
flake8-builtins = "2.0.0"
flake8-docstrings = "1.6.0"
flake8-eradicate = "1.4.0"
flake8-isort = "5.0.0"
flake8-logging-format = "0.8.1"
flake8-pep3101 = "2.0.0"
flake8-polyfill = "1.0.2"
flake8-quotes = "3.3.1"
pep8-naming = "0.13.2"
pydocstyle = "6.1.1"
pytest = "7.2.0"
pytest-cov = "4.0.0"
pytest-mock = "3.10.0"
yapf = "0.32.0"
toml = "0.10.2"
[tool.poetry.scripts] [tool.poetry.scripts]
prometheus-pve-sd = "prometheuspvesd.cli:main" prometheus-pve-sd = "prometheuspvesd.cli:main"
[tool.poetry.group.dev.dependencies]
ruff = "0.7.3"
pytest = "8.3.3"
pytest-mock = "3.14.0"
pytest-cov = "6.0.0"
toml = "0.10.2"
[tool.poetry-dynamic-versioning] [tool.poetry-dynamic-versioning]
enable = true enable = true
style = "semver" style = "semver"
vcs = "git" vcs = "git"
[tool.isort]
default_section = "THIRDPARTY"
force_single_line = true
line_length = 99
sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
skip_glob = ["**/.env*", "**/env/*", "**/.venv/*", "**/docs/*"]
[tool.pytest.ini_options] [tool.pytest.ini_options]
addopts = "prometheuspvesd --cov=prometheuspvesd --cov-report=xml:coverage.xml --cov-report=term --no-cov-on-fail" addopts = "prometheuspvesd --cov=prometheuspvesd --cov-report=xml:coverage.xml --cov-report=term-missing --no-cov-on-fail --cov-fail-under=80"
filterwarnings = [ filterwarnings = ["ignore::FutureWarning", "ignore::DeprecationWarning"]
"ignore::FutureWarning",
"ignore:.*distutils.*:DeprecationWarning",
"ignore:.*collections.*:DeprecationWarning",
"ignore:.*pep8.*:FutureWarning",
]
[tool.coverage.run] [tool.coverage.run]
omit = ["**/test/*"] omit = ["**/test/*"]
[build-system] [build-system]
build-backend = "poetry.core.masonry.api" build-backend = "poetry_dynamic_versioning.backend"
requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"] requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"]
[tool.ruff]
exclude = [
".git",
"__pycache__",
"build",
"dist",
"*.pyc",
"*.egg-info",
".cache",
".eggs",
"env*",
]
line-length = 99
indent-width = 4
[tool.ruff.lint]
# Explanation of errors
#
# D102: Missing docstring in public method
# D103: Missing docstring in public function
# D105: Missing docstring in magic method
# D107: Missing docstring in __init__
# D202: No blank lines allowed after function docstring
# D203: One blank line required before class docstring
# D212: Multi-line docstring summary should start at the first line
ignore = [
"D102",
"D103",
"D105",
"D107",
"D202",
"D203",
"D212",
"UP038",
"RUF012",
]
select = [
"D",
"E",
"F",
"Q",
"W",
"I",
"S",
"BLE",
"N",
"UP",
"B",
"A",
"C4",
"T20",
"SIM",
"RET",
"ARG",
"ERA",
"RUF",
]
[tool.ruff.lint.per-file-ignores]
"test_*.py" = ["S"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
line-ending = "lf"

View File

@ -1,4 +1,12 @@
{ {
"$schema": "https://docs.renovatebot.com/renovate-schema.json", "$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["github>thegeeklab/renovate-presets"] "extends": ["github>thegeeklab/renovate-presets"],
"packageRules": [
{
"matchManagers": ["woodpecker"],
"matchFileNames": [".woodpecker/test.yml"],
"matchPackageNames": ["docker.io/library/python"],
"enabled": false
}
]
} }

View File

@ -1,24 +0,0 @@
[flake8]
# Explanation of errors
#
# D102: Missing docstring in public method
# D103: Missing docstring in public function
# D105: Missing docstring in magic method
# D107: Missing docstring in __init__
# D202: No blank lines allowed after function docstring
# G001: Logging statements should not use string.format() for their first argument
# G004: Logging statements should not use f"..." for their first argument
# W503: Line break occurred before a binary operator
ignore = D102, D103, D105, D107, D202, G001, G004, W503
max-line-length = 99
inline-quotes = double
exclude = .git, __pycache__, build, dist, *.pyc, *.egg-info, .cache, .eggs, env*
[yapf]
based_on_style = google
column_limit = 99
dedent_closing_brackets = true
coalesce_brackets = true
split_before_logical_operator = true
indent_dictionary_value = true
allow_split_before_dict_value = false