Compare commits

...

318 Commits
v2.5.7 ... main

Author SHA1 Message Date
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
renovate[bot]
081e7784ed
chore(deps): lock file maintenance (#317) 2022-11-02 09:11:15 +01:00
renovate[bot]
52869fbb8a
fix(deps): update dependency jsonschema to v4.17.0 (#318) 2022-11-02 09:04:28 +01:00
renovate[bot]
c77b2a2d44 chore(deps): update dependency pytest to v7.2.0 2022-10-31 06:26:25 +00:00
renovate[bot]
6fccb14e3e chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.8 2022-10-26 02:03:04 +00:00
renovate[bot]
14431ee5e3
chore(deps): lock file maintenance (#307) 2022-10-25 21:30:38 +02:00
renovate[bot]
3996939f05
fix(deps): update dependency colorama to v0.4.6 (#310) 2022-10-25 21:30:28 +02:00
renovate[bot]
b29279ce1f
chore(deps): update arm64v8/python docker tag to v3.11 (#311) 2022-10-25 21:30:21 +02:00
renovate[bot]
45d83b2146
chore(deps): update python docker tag to v3.11 (#312) 2022-10-25 21:30:14 +02:00
renovate[bot]
47c59641bc
chore(deps): update arm32v7/python docker tag to v3.11 (#314) 2022-10-25 21:30:01 +02:00
renovate[bot]
4c1534b0bb chore(docker): update docker digests 2022-10-25 15:54:06 +00:00
renovate[bot]
fdc8cb0be7 chore(docker): update docker digests 2022-10-25 10:09:06 +00:00
renovate[bot]
70d1fb0d8a chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.7 2022-10-17 13:38:08 +00:00
renovate[bot]
cbfbca23e7 chore(docker): update docker digests 2022-10-14 17:55:45 +00:00
renovate[bot]
4c0baad5ee chore(docker): update docker digests 2022-10-14 06:05:31 +00:00
renovate[bot]
94504888ce
chore(deps): lock file maintenance (#293) 2022-10-13 21:19:35 +02:00
renovate[bot]
232e4f1b06
fix(deps): update dependency prometheus-client to v0.15.0 (#304) 2022-10-13 21:18:35 +02:00
renovate[bot]
d53ac62a71 chore(deps): update dependency pytest-mock to v3.10.0 2022-10-10 02:22:25 +00:00
renovate[bot]
70ec7b1da3
chore(deps): update dependency flake8-builtins to v2 (#300) 2022-10-09 16:31:01 +02:00
renovate[bot]
cb1c1660e9
chore(deps): update dependency flake8-pep3101 to v2 (#301) 2022-10-09 13:41:49 +02:00
renovate[bot]
d9678a010d
chore(deps): update dependency flake8-isort to v5 (#302) 2022-10-09 11:35:10 +02:00
renovate[bot]
ca3627b68b chore(docker): update python:3.10-alpine docker digest to 486782e 2022-10-08 04:46:34 +00:00
renovate[bot]
1d3ac33304 chore(docker): update docker digests 2022-10-07 13:53:03 +00:00
renovate[bot]
99ee939b47 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.6 2022-10-04 14:58:49 +00:00
renovate[bot]
e6e902cb40 chore(deps): update devdependencies (non-major) 2022-10-03 05:17:31 +00:00
renovate[bot]
eadd789ade
chore(deps): update dependency pytest-cov to v4 (#295) 2022-09-29 08:54:17 +02:00
renovate[bot]
af2fdffba5 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.5 2022-09-28 11:03:07 +00:00
renovate[bot]
2496371d0c chore(deps): update dependency flake8-eradicate to v1.4.0 2022-09-26 05:02:21 +00:00
renovate[bot]
5b62891dd0 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.4 2022-09-24 00:03:26 +00:00
renovate[bot]
f8762cb9a1
chore(deps): lock file maintenance (#289) 2022-09-19 09:07:38 +02:00
renovate[bot]
bccf18f0e9
fix(deps): update dependency jsonschema to v4.16.0 (#288) 2022-09-19 09:07:19 +02:00
renovate[bot]
99ddc9200a chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.3 2022-09-12 15:22:21 +00:00
renovate[bot]
5b06e32564 chore(docker): update docker digests 2022-09-08 14:54:28 +00:00
renovate[bot]
cbebad1832 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.2 2022-09-05 23:09:03 +00:00
renovate[bot]
8217c87920
chore(deps): lock file maintenance (#281) 2022-09-05 20:39:48 +02:00
renovate[bot]
5ee927d2b0
fix(deps): update dependency jsonschema to v4.15.0 (#283) 2022-09-05 20:39:18 +02:00
renovate[bot]
80470c1977 chore(deps): update dependency pytest to v7.1.3 2022-09-05 06:45:42 +00:00
renovate[bot]
d7d3a21179 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.1 2022-09-02 13:23:20 +00:00
renovate[bot]
0184389208 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.35.0 2022-08-30 15:28:35 +00:00
renovate[bot]
ed582c780e chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.34.2 2022-08-23 02:33:51 +00:00
renovate[bot]
219a346c76
fix(deps): update dependency jsonschema to v4.14.0 (#278)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-22 09:59:55 +02:00
renovate[bot]
49544a06aa
chore(deps): lock file maintenance (#256)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-22 09:59:27 +02:00
renovate[bot]
b49853cb60
chore(deps): update dependency flake8 to v5 (#262)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-22 08:40:09 +02:00
renovate[bot]
c4aa50c45a
chore(deps): update devdependencies (non-major) (#275) 2022-08-22 00:08:36 +02:00
renovate[bot]
3eeaaf1193
fix(deps): update dependency jsonschema to v4.13.0 (#277)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-19 22:26:47 +02:00
renovate[bot]
9b8893df8c
fix(deps): update dependency jsonschema to v4.12.1 (#276)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-18 21:58:19 +02:00
renovate[bot]
a0bb62d71e chore(docker): update docker digests 2022-08-11 05:58:28 +00:00
renovate[bot]
0fec18559f chore(docker): update docker digests to 3fe6aa2 2022-08-10 10:35:53 +00:00
renovate[bot]
2bbb120749 chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.34.1 2022-08-08 22:31:58 +00:00
renovate[bot]
8bfe06f00e
chore(deps): update dependency flake8-isort to v4.2.0 (#271)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-08 11:35:48 +02:00
renovate[bot]
9c2104f0be chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.34.0 2022-08-05 00:29:10 +00:00
renovate[bot]
7322b1ecec chore(docker): update python digest to 4543fd9 2022-08-04 00:26:33 +00:00
renovate[bot]
508cabcc0a
fix(deps): update dependency jsonschema to v4.9.1 (#268) 2022-08-03 20:17:56 +02:00
renovate[bot]
7eab4ebfd6 chore(docker): update docker digests to 4fd92f2 2022-08-03 17:17:09 +00:00
renovate[bot]
846e88d38a chore(docker): update python digest to ffc9076 2022-08-03 04:50:42 +00:00
renovate[bot]
89da41598e chore(deps): update dependency thegeeklab/hugo-geekdoc to v0.33.2 2022-08-02 03:52:31 +00:00
renovate[bot]
39daa0601d
fix(deps): update dependency jsonschema to v4.9.0 (#263) 2022-08-01 21:16:06 +02:00
renovate[bot]
d9704970b2 chore(deps): update dependency flake8-isort to v4.1.2.post0 2022-08-01 03:24:13 +00:00
renovate[bot]
93cfb71e48
fix(deps): update dependency jsonschema to v4.8.0 (#261) 2022-07-30 21:43:01 +02:00
renovate[bot]
a1a62483ca chore(docker): update docker digests to dcc75b5 2022-07-27 17:22:45 +00:00
renovate[bot]
025bd09325 chore(docker): update docker digests to fe93ef5 2022-07-27 05:42:35 +00:00
1d78ca1788
ci: switch to thegeeklab/drone-s3-sync plugin 2022-07-26 14:47:53 +02:00
49 changed files with 1708 additions and 2540 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: 'plugins/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: plugins/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: db7a2b6f2dc445d94276cd268a6e20bddf690d98eef2f6ad21a2326cb34c14fe
...

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,73 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
- name: build
image: docker.io/library/python:3.12
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry build
- name: dryrun
image: quay.io/thegeeklab/wp-docker-buildx:4
settings:
containerfile: Containerfile.multiarch
dry_run: true
platforms:
- linux/amd64
- linux/arm64
provenance: false
repo: ${CI_REPO}
when:
- event: [pull_request]
- name: publish-dockerhub
image: quay.io/thegeeklab/wp-docker-buildx:4
group: container
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:4
group: container
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.12
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.12
secrets:
- source: pypi_password
target: POETRY_HTTP_BASIC_PYPI_PASSWORD
- source: pypi_username
target: POETRY_HTTP_BASIC_PYPI_USERNAME
commands:
- pip install poetry poetry-dynamic-versioning -qq
- poetry publish -n
when:
- event: [tag]
depends_on:
- lint
- test

100
.woodpecker/docs.yml Normal file
View File

@ -0,0 +1,100 @@
---
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
group: test
commands:
- markdownlint 'README.md' 'CONTRIBUTING.md'
- name: spellcheck
image: quay.io/thegeeklab/alpine-tools
group: test
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
group: test
commands:
- lychee --no-progress --format detailed docs/content README.md
- name: build
image: quay.io/thegeeklab/hugo:0.125.7
commands:
- hugo --panicOnWarning -s docs/
- name: beautify
image: quay.io/thegeeklab/alpine-tools
commands:
- html-beautify -r -f 'docs/public/**/*.html'
environment:
FORCE_COLOR: "true"
- name: publish
image: quay.io/thegeeklab/wp-s3-action
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
secrets:
- source: docker_password
target: DOCKER_PASS
- source: docker_username
target: DOCKER_USER
environment:
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
secrets:
- source: quay_token
target: APIKEY__QUAY_IO
environment:
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

25
.woodpecker/lint.yml Normal file
View File

@ -0,0 +1,25 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
- name: check-format
image: docker.io/library/python:3.12
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.12
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
password:
from_secret: matrix_password
roomid:
from_secret: matrix_roomid
username:
from_secret: matrix_username
when:
- status: [success, failure]
depends_on:
- docs

39
.woodpecker/test.yml Normal file
View File

@ -0,0 +1,39 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
variables:
- &pytest_base
group: pytest
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-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
- name: python-39
image: docker.io/library/python:3.9
<<: *pytest_base
- name: python-38
image: docker.io/library/python:3.8
<<: *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.10-alpine@sha256:ba6cfcca463537621aac63ffda4f93cd73e1f3dea59a83287603fbebd02444e4 FROM python:3.12-alpine@sha256:5365725a6cd59b72a927628fdda9965103e3dc671676c89ef3ed8b8b0e22e812
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.33.1 THEME_VERSION := v0.45.0
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.10-alpine@sha256:8042f9a87f0b40b9291884dbd24cdd0bfc353b07f1e779e780ec125787e2d22f
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.10-alpine@sha256:5e8298ed17e5ee5dbc54175603463e67a6d539424f3f522bed48982a8ae1796f
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

1458
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)
@ -176,7 +181,7 @@ class PrometheusSD:
shutil.move(temp_file.name, self.config.config["output_file"]) shutil.move(temp_file.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)
@ -70,11 +69,11 @@ class MultilineJsonFormatter(jsonlogger.JsonFormatter):
class Log: class Log:
"""Handle logging.""" """Handle logging."""
def __init__(self, level=logging.WARN, name="prometheuspvesd", log_format="console"): def __init__(self, level=logging.WARNING, name="prometheuspvesd", log_format="console"):
self.logger = logging.getLogger(name) self.logger = logging.getLogger(name)
self.logger.setLevel(level) self.logger.setLevel(level)
self.logger.addHandler(self._get_error_handler(log_format)) self.logger.addHandler(self._get_error_handler(log_format))
self.logger.addHandler(self._get_warn_handler(log_format)) self.logger.addHandler(self._get_warning_handler(log_format))
self.logger.addHandler(self._get_info_handler(log_format)) self.logger.addHandler(self._get_info_handler(log_format))
self.logger.addHandler(self._get_critical_handler(log_format)) self.logger.addHandler(self._get_critical_handler(log_format))
self.logger.addHandler(self._get_debug_handler(log_format)) self.logger.addHandler(self._get_debug_handler(log_format))
@ -102,10 +101,10 @@ class Log:
return handler return handler
def _get_warn_handler(self, log_format): def _get_warning_handler(self, log_format):
handler = logging.StreamHandler(sys.stdout) handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.WARN) handler.setLevel(logging.WARNING)
handler.addFilter(LogFilter(logging.WARN)) handler.addFilter(LogFilter(logging.WARNING))
if log_format == "json": if log_format == "json":
handler.setFormatter(MultilineJsonFormatter(JSON_FORMAT)) handler.setFormatter(MultilineJsonFormatter(JSON_FORMAT))
@ -114,7 +113,7 @@ class Log:
else: else:
handler.setFormatter( handler.setFormatter(
MultilineFormatter( MultilineFormatter(
self.warn( self.warning(
CONSOLE_FORMAT.format( CONSOLE_FORMAT.format(
colorama.Fore.YELLOW, colorama.Style.BRIGHT, colorama.Style.RESET_ALL colorama.Fore.YELLOW, colorama.Style.BRIGHT, colorama.Style.RESET_ALL
) )
@ -196,7 +195,7 @@ class Log:
self.logger.setLevel(level) self.logger.setLevel(level)
self.logger.addHandler(self._get_error_handler(log_level)) self.logger.addHandler(self._get_error_handler(log_level))
self.logger.addHandler(self._get_warn_handler(log_level)) self.logger.addHandler(self._get_warning_handler(log_level))
self.logger.addHandler(self._get_info_handler(log_level)) self.logger.addHandler(self._get_info_handler(log_level))
self.logger.addHandler(self._get_critical_handler(log_level)) self.logger.addHandler(self._get_critical_handler(log_level))
self.logger.addHandler(self._get_debug_handler(log_level)) self.logger.addHandler(self._get_debug_handler(log_level))
@ -213,8 +212,8 @@ class Log:
"""Format error messages and return string.""" """Format error messages and return string."""
return msg return msg
def warn(self, msg): def warning(self, msg):
"""Format warn messages and return string.""" """Format warning messages and return string."""
return msg return msg
def info(self, msg): def info(self, msg):
@ -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,11 @@ 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.8",
"Programming Language :: Python :: 3.9", "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",
"Topic :: Utilities", "Topic :: Utilities",
] ]
description = "Prometheus Service Discovery for Proxmox VE." description = "Prometheus Service Discovery for Proxmox VE."
@ -29,66 +30,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.5" colorama = "0.4.6"
environs = "9.5.0" environs = "11.0.0"
jsonschema = "4.7.2" jsonschema = "4.22.0"
nested-lookup = "0.2.25" nested-lookup = "0.2.25"
prometheus-client = "0.14.1" prometheus-client = "0.20.0"
proxmoxer = "1.3.1" proxmoxer = "2.0.1"
python = "^3.7.0" python = "^3.8.0"
python-json-logger = "2.0.4" python-json-logger = "2.0.7"
requests = "2.28.1" requests = "2.31.0"
"ruamel.yaml" = "0.17.21" "ruamel.yaml" = "0.18.6"
[tool.poetry.dev-dependencies]
bandit = "1.7.4"
flake8 = "4.0.1"
flake8-blind-except = "0.2.1"
flake8-builtins = "1.5.3"
flake8-docstrings = "1.6.0"
flake8-eradicate = "1.2.1"
flake8-isort = "4.1.1"
flake8-logging-format = "0.6.0"
flake8-pep3101 = "1.3.0"
flake8-polyfill = "1.0.2"
flake8-quotes = "3.3.1"
pep8-naming = "0.13.1"
pydocstyle = "6.1.1"
pytest = "7.1.2"
pytest-cov = "3.0.0"
pytest-mock = "3.8.2"
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.4.5"
pytest = "8.2.1"
pytest-mock = "3.14.0"
pytest-cov = "5.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,22 +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
# W503:Line break occurred before a binary operator
ignore = D102, D103, D105, D107, D202, 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